diff --git a/app/srv/ws/sync/actions.ts b/app/srv/ws/sync/actions.ts index 111a0851..95daed46 100644 --- a/app/srv/ws/sync/actions.ts +++ b/app/srv/ws/sync/actions.ts @@ -67,12 +67,12 @@ export const SyncActions = { bin: Uint8Array ) => ({}) as { diff: Uint8Array; sv: Uint8Array } | void, diff_local: async ( - mode: "page" | "comp" | "site" | "code", + mode: "page" | "comp" | "site" , id: string, bin: Uint8Array ) => {}, sv_remote: async ( - mode: "page" | "comp" | "site" | "code", + mode: "page" | "comp" | "site" , id: string, sv: Uint8Array, diff: Uint8Array diff --git a/app/srv/ws/sync/actions/yjs_sv_remote.ts b/app/srv/ws/sync/actions/yjs_sv_remote.ts index 7bfff072..d8b47959 100644 --- a/app/srv/ws/sync/actions/yjs_sv_remote.ts +++ b/app/srv/ws/sync/actions/yjs_sv_remote.ts @@ -15,10 +15,7 @@ export const yjs_sv_remote: SAction["yjs"]["sv_remote"] = async function ( return; } let doc = null; - if (mode !== "code") doc = docs[mode][id].doc; - else { - doc = docs.code[id].build.site; - } + doc = docs[mode][id].doc; const diff_local = Y.encodeStateAsUpdate(doc as any, await gunzipAsync(sv)); Y.applyUpdate(doc as any, await gunzipAsync(diff), "local"); return { diff: await gzipAsync(diff_local) }; diff --git a/app/srv/ws/sync/editor/code/build-code.ts b/app/srv/ws/sync/editor/code/build-code.ts index cb1f431d..f413a81a 100644 --- a/app/srv/ws/sync/editor/code/build-code.ts +++ b/app/srv/ws/sync/editor/code/build-code.ts @@ -2,11 +2,20 @@ import globalExternals from "@fal-works/esbuild-plugin-global-externals"; import { style } from "@hyrious/esbuild-plugin-style"; import { context } from "esbuild"; import { dirAsync, existsAsync, removeAsync, writeAsync } from "fs-jetpack"; -import { DCode } from "../../../../../web/src/utils/types/root"; -import { readDirectoryRecursively } from "../../../../api/site-export"; -import { docs } from "../../entity/docs"; -import { code } from "./util-code"; import { server } from "./server-main"; +import { code } from "./util-code"; +import { user } from "../../entity/user"; +import { conns } from "../../entity/conn"; +import { SyncType } from "../../type"; +import { Packr } from "msgpackr"; +import { ServerWebSocket } from "bun"; +import { WSData } from "../../../../../../pkgs/core/server/create"; + +const packr = new Packr({ structuredClone: true }); + +const sendWS = (ws: ServerWebSocket, msg: any) => { + ws.sendBinary(packr.pack(msg)); +}; export const codeBuild = async (id_site: any) => { const src_path = code.path(id_site, "site", "src"); @@ -185,14 +194,21 @@ if (typeof global.server_hook === "function") { "site" ); } - const cdoc = docs.code[id_site]; - if (cdoc) { - const doc = cdoc.build["site"]; - const build_dir = code.path(id_site, "site", "build"); - if (doc) { - codeApplyChanges(build_dir, doc); + + const client_ids = new Set(); + user.active.findAll({ site_id: id_site }).forEach((e) => { + client_ids.add(e.client_id); + }); + + client_ids.forEach((client_id) => { + const ws = conns.get(client_id)?.ws; + if (ws) { + sendWS(ws, { + type: SyncType.Event, + event: "code_changes", + }); } - } + }); }); }, }, @@ -223,27 +239,27 @@ if (typeof global.server_hook === "function") { } }; -const codeApplyChanges = (path: string, doc: DCode) => { - const map = doc.getMap("map"); +// const codeApplyChanges = (path: string, doc: DCode) => { +// const map = doc.getMap("map"); - const files = map.get("files"); +// const files = map.get("files"); - const dirs = readDirectoryRecursively(path); - doc.transact(() => { - files?.forEach((v, k) => { - if (!dirs[k]) { - files?.delete(k); - } - }); - for (const [k, v] of Object.entries(dirs)) { - if (files) { - files.set(k, v); - } - } - }); +// const dirs = readDirectoryRecursively(path); +// doc.transact(() => { +// files?.forEach((v, k) => { +// if (!dirs[k]) { +// files?.delete(k); +// } +// }); +// for (const [k, v] of Object.entries(dirs)) { +// if (files) { +// files.set(k, v); +// } +// } +// }); - return doc; -}; +// return doc; +// }; const codeError = async ( id_site: string, diff --git a/app/srv/ws/sync/editor/code/prep-code.ts b/app/srv/ws/sync/editor/code/prep-code.ts index 546560c4..b603d936 100644 --- a/app/srv/ws/sync/editor/code/prep-code.ts +++ b/app/srv/ws/sync/editor/code/prep-code.ts @@ -1,15 +1,5 @@ -import { Doc } from "yjs"; -import { DCode } from "../../../../../web/src/utils/types/root"; -import { readDirectoryRecursively } from "../../../../api/site-export"; -import { docs } from "../../entity/docs"; -import { snapshot } from "../../entity/snapshot"; -import { gzipAsync } from "../../entity/zlib"; import { codeBuild } from "./build-code"; import { CodeMode, code } from "./util-code"; -import { user } from "../../entity/user"; -import { SyncType } from "../../type"; -import { sendWS } from "../../sync-handler"; -import { conns } from "../../entity/conn"; export const prepCodeSnapshot = async (id_site: string, mode: CodeMode) => { await code @@ -21,100 +11,5 @@ export const prepCodeSnapshot = async (id_site: string, mode: CodeMode) => { ) .await(); - let dcode = docs.code[id_site]; - if (!docs.code[id_site]) { - docs.code[id_site] = { - id: id_site, - build: {}, - }; - dcode = docs.code[id_site]; - } - - if (dcode) { - if (!dcode.build[mode]) { - const build_dir = code.path(id_site, mode, "build"); - - await codeBuild(id_site); - - dcode.build[mode] = codeLoad(id_site, build_dir); - const doc = dcode.build[mode] as Doc; - if (doc) { - doc.on("update", async (e, origin) => { - const bin = Y.encodeStateAsUpdate(doc); - - if (typeof snap !== "undefined" && snap.type === "code") { - snap.build[mode].bin = bin; - snapshot.update({ - id: id_site, - type: "code", - build: snap.build, - }); - } - const sv_local = await gzipAsync(bin); - - const client_ids = new Set(); - user.active.findAll({ site_id: id_site }).forEach((e) => { - client_ids.add(e.client_id); - }); - - client_ids.forEach((client_id) => { - const ws = conns.get(client_id)?.ws; - if (ws) - sendWS(ws, { - type: SyncType.Event, - event: "remote_svlocal", - data: { type: "code", sv_local, id: id_site }, - }); - }); - }); - } - } - - const build: Record< - string, - { - id_doc: number; - bin: Uint8Array; - } - > = {}; - - for (const [k, v] of Object.entries(dcode.build)) { - const bin = Y.encodeStateAsUpdate(v as Doc); - build[k] = { bin: bin, id_doc: v.clientID }; - } - - let snap = await snapshot.getOrCreate({ - type: "code", - id: id_site, - build, - }); - - if (snap.type === "code") { - snapshot.update({ - id: id_site, - type: "code", - build, - }); - return snap; - } - } -}; - -const codeLoad = (id: string, path: string) => { - const doc = new Y.Doc() as DCode; - const map = doc.getMap("map"); - - const files = new Y.Map(); - - const dirs = readDirectoryRecursively(path); - for (const [k, v] of Object.entries(dirs)) { - files.set(k, v); - } - - doc.transact(() => { - map.set("files", files as any); - map.set("id", id); - }); - - return doc; + await codeBuild(id_site); }; diff --git a/app/web/src/nova/ed/logic/ed-sync.tsx b/app/web/src/nova/ed/logic/ed-sync.tsx index 0b875461..e8a1fca7 100644 --- a/app/web/src/nova/ed/logic/ed-sync.tsx +++ b/app/web/src/nova/ed/logic/ed-sync.tsx @@ -182,14 +182,33 @@ export const edInitSync = (p: PG) => { } p.render(); }, + async code_changes() { + const w = window as any; + + const url = `/prod/${ + p.site.id + }/_prasi/code/index.js?ts=${Date.now()}`; + const fn = new Function( + "callback", + `import("${url}").then(callback)` + ); + await new Promise((resolve) => { + fn((exports: any) => { + for (const [k, v] of Object.entries(exports)) { + w[k] = v; + } + resolve(); + }); + }); + await treeRebuild(p); + p.render(); + }, async remote_svlocal(data) { let doc = null as any; if (data.type === "page" && p.page.cur.id === data.id) { doc = p.page.doc as Y.Doc; } else if (data.type === "comp" && p.comp.list[data.id]) { doc = p.comp.list[data.id].doc; - } else if (data.type === "code") { - doc = p.code.site.doc; } if (doc && p.sync) { diff --git a/app/web/src/utils/sync/ws-client.ts b/app/web/src/utils/sync/ws-client.ts index c2a21916..7be732b3 100644 --- a/app/web/src/utils/sync/ws-client.ts +++ b/app/web/src/utils/sync/ws-client.ts @@ -79,7 +79,7 @@ export const clientStartSync = async (arg: { events: { editor_start: (arg: UserConf) => void; remote_svlocal: (arg: { - type: "page" | "comp" | "code"; + type: "page" | "comp"; id: string; sv_local: Uint8Array; }) => void; @@ -91,6 +91,7 @@ export const clientStartSync = async (arg: { } > ) => void; + code_changes: () => void; disconnected: () => { reconnect: boolean }; opened: () => void; shakehand: (client_id: string) => void;