fix watcher

This commit is contained in:
Rizky 2023-11-09 20:29:32 +07:00
parent f620760929
commit ac34579b84
7 changed files with 146 additions and 31 deletions

View File

@ -82,7 +82,7 @@ export const SyncActions = {
id: string;
}
| { type: "code"; id: string; name: string; action: "open" | "close" }
) => {},
) => ({}) as any,
client: {
info: async (client_ids: string[]) =>
({}) as Record<string, { id: string; username: string }>,

View File

@ -2,7 +2,11 @@ import { SAction } from "../actions";
import { SyncConnection } from "../type";
import { activity as a } from "../entity/activity";
import { prepCode } from "../editor/code/prep-code";
import { Code, startCodeWatcher, stopCodeWatcher } from "../editor/code/watcher";
import {
Code,
startCodeWatcher,
stopCodeWatcher,
} from "../editor/code/watcher";
export const activity: SAction["activity"] = async function (
this: SyncConnection,
name,
@ -32,5 +36,7 @@ export const activity: SAction["activity"] = async function (
stopCodeWatcher(code.id);
}
}
return code.id;
}
};

View File

@ -1,7 +1,27 @@
import { dir } from "dir";
import { g } from "utils/global";
import { dirAsync } from "fs-jetpack";
export type DBCode = Exclude<Awaited<ReturnType<typeof getCode>>, null>;
export const prepCode = async (site_id: string, name: string) => {
let code = await getCode(site_id);
const pkgfile = Bun.file(dir.path(`${g.datadir}/site/code/package.json`));
if (!(await pkgfile.exists())) {
await dirAsync(dir.path(`${g.datadir}/site/code`));
await Bun.write(
pkgfile,
JSON.stringify(
{
name: "code",
workspaces: ["./*"],
},
null,
2
)
);
}
if (code) return code;
let new_code = await db.code.create({
data: {

View File

@ -7,9 +7,12 @@ import { dirname } from "path";
import { spawn } from "bun";
export const Code = {
watchers: {} as Record<string, ReturnType<typeof watch>>,
watchers: {} as Record<
string,
{ id: string; watcher: ReturnType<typeof watch> }
>,
path: (id: string, p?: string) => {
return dir.path(`${g.datadir}/code/${id}${p ? "/" + p : ""}`);
return dir.path(`${g.datadir}/site/code/${id}${p ? "/" + p : ""}`);
},
};
@ -18,16 +21,25 @@ export const startCodeWatcher = async (code: DBCode) => {
return;
}
let delay = false;
const indexes = {} as Record<string, (typeof code)["code_file"][0]>;
for (const c of code.code_file) {
const path = Code.path(c.id_code, c.path);
indexes[c.path] = c;
const file = Bun.file(path);
if (!(await file.exists())) {
await dirAsync(dirname(path));
await Bun.write(file, c.content);
delay = true;
}
}
if (delay) {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
await spawn({
cmd: ["bun", "i"],
cwd: Code.path(code.id),
@ -35,18 +47,72 @@ export const startCodeWatcher = async (code: DBCode) => {
stdout: "ignore",
}).exited;
Code.watchers[code.id] = watch(
Code.path(code.id),
{ recursive: true },
(event, path) => {
console.log(event, path);
}
);
Code.watchers[code.id] = {
id: code.id,
watcher: watch(
Code.path(code.id),
{ recursive: true },
async (event, path) => {
if (path) {
const file = Bun.file(Code.path(code.id, path));
const item = indexes[path];
if (event === "change") {
if (item) {
console.log(path, await file.text());
await db.code_file.update({
where: {
path_id_code: { id_code: item.id_code, path: item.path },
},
data: {
content: await file.text(),
},
});
}
} else {
if (await file.exists()) {
if (!item) {
await new Promise((resolve) => setTimeout(resolve, 500));
const data = {
id_code: code.id,
path,
content: await file.text(),
};
await db.code_file.create({
data,
});
indexes[path] = data;
} else {
await db.code_file.update({
where: {
path_id_code: { id_code: item.id_code, path: item.path },
},
data: {
content: await file.text(),
},
});
}
} else {
if (item) {
await db.code_file.delete({
where: {
path_id_code: { id_code: item.id_code, path: item.path },
},
});
}
}
}
}
}
),
};
};
export const stopCodeWatcher = async (id_code: string) => {
if (Code.watchers[id_code]) {
Code.watchers[id_code].close();
Code.watchers[id_code].watcher.close();
delete Code.watchers[id_code];
}
};

View File

@ -6,6 +6,7 @@ import { createAPI, createDB, reloadDBAPI } from "./utils/script/init-api";
import { w } from "./utils/types/general";
import * as Y from "yjs";
import { registerMobile } from "./render/live/logic/mobile";
import { isLocalhost } from "./utils/ui/is-localhost";
(window as any).Y = Y;
@ -16,11 +17,7 @@ const start = async () => {
};
(window as any).mobile = registerMobile();
if (
!["localhost", "127.0.0.1", "trycloudflare.com", "ngrok"].find((e) =>
location.hostname.includes(e)
)
) {
if (!isLocalhost()) {
const sw = await registerServiceWorker();
const cacheCurrentPage = () => {

View File

@ -1,29 +1,44 @@
import { useGlobal } from "web-utils";
import { useGlobal, useLocal } from "web-utils";
import { EDGlobal } from "../../../logic/ed-global";
import { Modal } from "../../../../../utils/ui/modal";
import { useEffect } from "react";
import { isLocalhost } from "../../../../../utils/ui/is-localhost";
import { Loading } from "../../../../../utils/ui/loading";
export const EdPopCode = () => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ id_code: "" });
useEffect(() => {
if (p.ui.popup.code.init) {
p.sync.activity("site", {
action: p.ui.popup.code.open ? "open" : "close",
id: p.site.id,
type: "code",
name: "main",
});
}
p.ui.popup.code.init = true;
(async () => {
if (p.ui.popup.code.init) {
const id_code = await p.sync.activity("site", {
action: p.ui.popup.code.open ? "open" : "close",
id: p.site.id,
type: "code",
name: "main",
});
if (id_code) {
local.id_code = id_code;
local.render();
}
}
p.ui.popup.code.init = true;
})();
}, [p.ui.popup.code.open]);
const vscode_url = isLocalhost()
? "http://localhost:3000?"
: "https://code.web.andromedia.co.id?tkn=prasi&";
return (
<Modal
fade={false}
open={p.ui.popup.code.open}
onOpenChange={(open) => {
if (!open) {
console.clear();
p.ui.popup.code.open = false;
p.render();
}
@ -50,10 +65,16 @@ export const EdPopCode = () => {
<div>Site</div>
</div>
</div>
<iframe
className="flex flex-1"
src="http://localhost:3000/?folder=/site"
></iframe>
{!local.id_code ? (
<div className="flex flex-1 relative">
<Loading backdrop={false} />
</div>
) : (
<iframe
className="flex flex-1"
src={`${vscode_url}folder=/site/code/${local.id_code}`}
></iframe>
)}
</div>
</Modal>
);

View File

@ -0,0 +1,5 @@
export const isLocalhost = () => {
return ["localhost", "127.0.0.1", "trycloudflare.com", "ngrok"].find((e) =>
location.hostname.includes(e)
);
};