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; id: string;
} }
| { type: "code"; id: string; name: string; action: "open" | "close" } | { type: "code"; id: string; name: string; action: "open" | "close" }
) => {}, ) => ({}) as any,
client: { client: {
info: async (client_ids: string[]) => info: async (client_ids: string[]) =>
({}) as Record<string, { id: string; username: string }>, ({}) as Record<string, { id: string; username: string }>,

View File

@ -2,7 +2,11 @@ import { SAction } from "../actions";
import { SyncConnection } from "../type"; import { SyncConnection } from "../type";
import { activity as a } from "../entity/activity"; import { activity as a } from "../entity/activity";
import { prepCode } from "../editor/code/prep-code"; 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 ( export const activity: SAction["activity"] = async function (
this: SyncConnection, this: SyncConnection,
name, name,
@ -32,5 +36,7 @@ export const activity: SAction["activity"] = async function (
stopCodeWatcher(code.id); 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 type DBCode = Exclude<Awaited<ReturnType<typeof getCode>>, null>;
export const prepCode = async (site_id: string, name: string) => { export const prepCode = async (site_id: string, name: string) => {
let code = await getCode(site_id); 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; if (code) return code;
let new_code = await db.code.create({ let new_code = await db.code.create({
data: { data: {

View File

@ -7,9 +7,12 @@ import { dirname } from "path";
import { spawn } from "bun"; import { spawn } from "bun";
export const Code = { 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) => { 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; return;
} }
let delay = false;
const indexes = {} as Record<string, (typeof code)["code_file"][0]>;
for (const c of code.code_file) { for (const c of code.code_file) {
const path = Code.path(c.id_code, c.path); const path = Code.path(c.id_code, c.path);
indexes[c.path] = c;
const file = Bun.file(path); const file = Bun.file(path);
if (!(await file.exists())) { if (!(await file.exists())) {
await dirAsync(dirname(path)); await dirAsync(dirname(path));
await Bun.write(file, c.content); await Bun.write(file, c.content);
delay = true;
} }
} }
if (delay) {
await new Promise((resolve) => setTimeout(resolve, 1000));
}
await spawn({ await spawn({
cmd: ["bun", "i"], cmd: ["bun", "i"],
cwd: Code.path(code.id), cwd: Code.path(code.id),
@ -35,18 +47,72 @@ export const startCodeWatcher = async (code: DBCode) => {
stdout: "ignore", stdout: "ignore",
}).exited; }).exited;
Code.watchers[code.id] = watch( Code.watchers[code.id] = {
Code.path(code.id), id: code.id,
{ recursive: true }, watcher: watch(
(event, path) => { Code.path(code.id),
console.log(event, path); { 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) => { export const stopCodeWatcher = async (id_code: string) => {
if (Code.watchers[id_code]) { if (Code.watchers[id_code]) {
Code.watchers[id_code].close(); Code.watchers[id_code].watcher.close();
delete Code.watchers[id_code]; 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 { w } from "./utils/types/general";
import * as Y from "yjs"; import * as Y from "yjs";
import { registerMobile } from "./render/live/logic/mobile"; import { registerMobile } from "./render/live/logic/mobile";
import { isLocalhost } from "./utils/ui/is-localhost";
(window as any).Y = Y; (window as any).Y = Y;
@ -16,11 +17,7 @@ const start = async () => {
}; };
(window as any).mobile = registerMobile(); (window as any).mobile = registerMobile();
if ( if (!isLocalhost()) {
!["localhost", "127.0.0.1", "trycloudflare.com", "ngrok"].find((e) =>
location.hostname.includes(e)
)
) {
const sw = await registerServiceWorker(); const sw = await registerServiceWorker();
const cacheCurrentPage = () => { 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 { EDGlobal } from "../../../logic/ed-global";
import { Modal } from "../../../../../utils/ui/modal"; import { Modal } from "../../../../../utils/ui/modal";
import { useEffect } from "react"; import { useEffect } from "react";
import { isLocalhost } from "../../../../../utils/ui/is-localhost";
import { Loading } from "../../../../../utils/ui/loading";
export const EdPopCode = () => { export const EdPopCode = () => {
const p = useGlobal(EDGlobal, "EDITOR"); const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ id_code: "" });
useEffect(() => { useEffect(() => {
if (p.ui.popup.code.init) { (async () => {
p.sync.activity("site", { if (p.ui.popup.code.init) {
action: p.ui.popup.code.open ? "open" : "close", const id_code = await p.sync.activity("site", {
id: p.site.id, action: p.ui.popup.code.open ? "open" : "close",
type: "code", id: p.site.id,
name: "main", type: "code",
}); name: "main",
} });
p.ui.popup.code.init = true;
if (id_code) {
local.id_code = id_code;
local.render();
}
}
p.ui.popup.code.init = true;
})();
}, [p.ui.popup.code.open]); }, [p.ui.popup.code.open]);
const vscode_url = isLocalhost()
? "http://localhost:3000?"
: "https://code.web.andromedia.co.id?tkn=prasi&";
return ( return (
<Modal <Modal
fade={false} fade={false}
open={p.ui.popup.code.open} open={p.ui.popup.code.open}
onOpenChange={(open) => { onOpenChange={(open) => {
if (!open) { if (!open) {
console.clear();
p.ui.popup.code.open = false; p.ui.popup.code.open = false;
p.render(); p.render();
} }
@ -50,10 +65,16 @@ export const EdPopCode = () => {
<div>Site</div> <div>Site</div>
</div> </div>
</div> </div>
<iframe {!local.id_code ? (
className="flex flex-1" <div className="flex flex-1 relative">
src="http://localhost:3000/?folder=/site" <Loading backdrop={false} />
></iframe> </div>
) : (
<iframe
className="flex flex-1"
src={`${vscode_url}folder=/site/code/${local.id_code}`}
></iframe>
)}
</div> </div>
</Modal> </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)
);
};