diff --git a/app/db/package.json b/app/db/package.json index 7b4b350b..abad046c 100644 --- a/app/db/package.json +++ b/app/db/package.json @@ -1,7 +1,7 @@ { "name": "db", "dependencies": { - "@prisma/client": "^5.6.0", - "prisma": "^5.6.0" + "@prisma/client": "^5.7.1", + "prisma": "^5.7.1" } } diff --git a/app/db/prisma/schema.prisma b/app/db/prisma/schema.prisma index e9de2352..d3d246a3 100644 --- a/app/db/prisma/schema.prisma +++ b/app/db/prisma/schema.prisma @@ -4,7 +4,7 @@ generator client { datasource db { provider = "postgresql" - url = "postgresql://postgres:a5f64103e7ba098d@web.andromedia.co.id:5446/prasi?schema=public" + url = env("DATABASE_URL") } model billing_account { diff --git a/app/srv/package.json b/app/srv/package.json index 2df086ed..f0440012 100644 --- a/app/srv/package.json +++ b/app/srv/package.json @@ -6,16 +6,16 @@ "@hyrious/esbuild-plugin-style": "^0.3.5", "@node-rs/argon2": "^1.5.2", "@paralleldrive/cuid2": "^2.2.2", - "@types/mime-types": "^2.1.2", + "@types/mime-types": "^2.1.4", "recast": "^0.23.4", - "esbuild": "^0.19.4", - "lmdb": "^2.8.5", + "esbuild": "^0.19.10", + "lmdb": "^2.9.2", "mime-types": "^2.1.35", - "msgpackr": "^1.9.9", + "msgpackr": "^1.10.0", "radix3": "^1.1.0", "uuid": "^9.0.1", "y-pojo": "^0.0.8", - "yjs": "^13.6.8", + "yjs": "^13.6.10", "yjs-types": "^0.0.1" } } diff --git a/app/srv/ws/sync/entity/user.ts b/app/srv/ws/sync/entity/user.ts index efa5074b..fd90865e 100644 --- a/app/srv/ws/sync/entity/user.ts +++ b/app/srv/ws/sync/entity/user.ts @@ -37,10 +37,12 @@ export const user = { }, async getOrCreate(user_id: string) { let res = this.db.get(user_id); + if (!res) { await this.db.put(user_id, structuredClone(defaultConf)); res = this.db.get(user_id); } + return res as UserConf; }, get(user_id: string) { diff --git a/app/srv/ws/sync/sync-handler.ts b/app/srv/ws/sync/sync-handler.ts index 9a60a39d..aff4e5f8 100644 --- a/app/srv/ws/sync/sync-handler.ts +++ b/app/srv/ws/sync/sync-handler.ts @@ -47,8 +47,8 @@ export const syncHandler: WebSocketHandler = { const msg = packr.unpack(Buffer.from(raw)); if (msg.type === SyncType.UserID) { const { user_id, page_id, site_id } = msg; - conn.user_id = user_id; + conn.user = await db.user.findFirst({ where: { id: user_id } }); let conf = await user.conf.getOrCreate(user_id); if (site_id) { @@ -57,7 +57,6 @@ export const syncHandler: WebSocketHandler = { } else if (!conf.site_id) { await loadDefaultSite(user_id); } - conn.conf = new Proxy(conf, { get(_, p) { const conf = user.conf.get(user_id); @@ -85,7 +84,6 @@ export const syncHandler: WebSocketHandler = { } if (baseAction) { const action = baseAction.bind(conn); - sendWS(ws, { type: SyncType.ActionResult, argid: msg.argid, diff --git a/app/web/package.json b/app/web/package.json index 7a50be9e..0009ebc2 100644 --- a/app/web/package.json +++ b/app/web/package.json @@ -6,9 +6,9 @@ "maxParallelRequests": 20 }, "dependencies": { - "@babel/parser": "^7.23.0", - "@floating-ui/react": "^0.26.1", - "@leeoniya/ufuzzy": "^1.0.11", + "@babel/parser": "^7.23.6", + "@floating-ui/react": "^0.26.4", + "@leeoniya/ufuzzy": "^1.0.14", "@minoru/react-dnd-treeview": "^3.4.4", "@monaco-editor/react": "^4.6.0", "@paralleldrive/cuid2": "2.2.2", @@ -17,12 +17,13 @@ "@parcel/service-worker": "^2.10.3", "recast": "^0.23.4", "@qiwi/deep-proxy": "^2.0.3", - "algoliasearch": "^4.20.0", + "algoliasearch": "^4.22.0", "date-fns": "^2.30.0", + "fast-safe-stringify": "^2.1.1", "dbgen": "workspace:*", - "downshift": "^8.2.2", - "esbuild-wasm": "^0.19.5", - "hash-wasm": "^4.10.0", + "downshift": "^8.2.3", + "esbuild-wasm": "^0.19.10", + "hash-wasm": "^4.11.0", "idb-keyval": "^6.2.1", "immer": "^10.0.3", "js-base64": "^3.7.5", @@ -42,9 +43,9 @@ "lodash.uniq": "^4.5.0", "lodash.uniqby": "^4.7.0", "monaco-jsx-syntax-highlight-v2": "^1.2.2", - "msgpackr": "^1.9.9", + "msgpackr": "^1.10.0", "polywasm": "^0.1.4", - "prettier": "3.0.3", + "prettier": "3.1.1", "prop-types": "^15.8.1", "quill-delta": "^5.1.0", "radix3": "^1.1.0", @@ -53,19 +54,18 @@ "react-dnd": "^16.0.1", "react-dom": "18.2.0", "react-is": "^18.2.0", - "react-select": "^5.7.7", "react-use-error-boundary": "^3.0.0", "react-virtuoso": "^4.6.2", "safe-stable-stringify": "^2.4.3", - "svgo": "^3.0.2", + "svgo": "^3.1.0", "textdiff-create": "^1.1.10", "tinycolor2": "^1.6.0", - "ua-parser-js": "^1.0.36", + "ua-parser-js": "^1.0.37", "uuid": "9.0.1", "wasm-gzip": "^2.0.3", "web-utils": "workspace:*", "y-pojo": "^0.0.8", - "yjs": "^13.6.8", + "yjs": "^13.6.10", "yjs-types": "^0.0.1" }, "devDependencies": { diff --git a/app/web/src/index.tsx b/app/web/src/index.tsx index 209317c5..73d3e288 100644 --- a/app/web/src/index.tsx +++ b/app/web/src/index.tsx @@ -20,8 +20,12 @@ const start = async () => { const base_url = `${cur.protocol}//${cur.host}`; w.db = dbProxy(base_url); - await loadApiProxyDef(base_url, false); - w.api = apiProxy(base_url); + try { + await loadApiProxyDef(base_url, false); + w.api = apiProxy(base_url); + } catch (e) { + console.warn("Failed to load API:", base_url); + } w.serverurl = base; diff --git a/app/web/src/nova/ed/logic/ed-site.ts b/app/web/src/nova/ed/logic/ed-site.ts index 6cdb555d..0a0be350 100644 --- a/app/web/src/nova/ed/logic/ed-site.ts +++ b/app/web/src/nova/ed/logic/ed-site.ts @@ -3,7 +3,6 @@ import { ESite, PG } from "./ed-global"; import { reloadPage } from "./ed-route"; export const loadSite = async (p: PG, site: ESite, note: string) => { - console.log("note", note); const old_layout_id = p.site.layout.id; const layout_changed = p.site.layout.id !== site.layout.id; p.site = site; diff --git a/app/web/src/nova/ed/panel/main/main-per-item.tsx b/app/web/src/nova/ed/panel/main/main-per-item.tsx index d2ec10ec..cfc500cd 100644 --- a/app/web/src/nova/ed/panel/main/main-per-item.tsx +++ b/app/web/src/nova/ed/panel/main/main-per-item.tsx @@ -147,6 +147,7 @@ export const mainPerItemVisit = ( active.hover.renderTree(); }; parts.props.onPointerDown = (e) => { + console.log(p); e.stopPropagation(); if ((meta.item as IContent).type === "text") { diff --git a/app/web/src/nova/ed/panel/popup/script/scope/extract-exim.tsx b/app/web/src/nova/ed/panel/popup/script/scope/extract-exim.tsx index 6391024b..ec376ef3 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/extract-exim.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/extract-exim.tsx @@ -1,23 +1,27 @@ import { IMeta, PG } from "../../../../logic/ed-global"; export const extractExportImport = (p: PG, m: IMeta, imports: string[]) => { - let _export = {}; - + const new_imports = [...imports]; const def = m.scope.def; if (def) { + let res: null | ReturnType = null; if (def.local) { - const local = extractLocal(p, m, def, imports); - if (local) { - for (const [k, v] of Object.entries(local)) { - v.names.forEach((n) => - imports.push(`import { ${n} } from "./${k}";`) - ); - } + res = extractLocal(p, m, def, imports); + } else if (def.passprop) { + res = extractPassProp(p, m, def, imports); + } else if (def.props) { + res = extractProps(p, m, def, imports); + } + if (res) { + for (const [k, v] of Object.entries(res)) { + v.names.forEach((n) => + new_imports.push(`import { ${n} } from "./${k}";`) + ); } } } - return _export; + return { imports: new_imports }; }; const extractLocal = ( @@ -107,7 +111,7 @@ const extractProps = ( exports.push(`export const ${e} = ${v.value};`); } } - + result.src = `\ ${imports.join("\n")} ${exports.join("\n")} diff --git a/app/web/src/nova/ed/panel/popup/script/scope/scope-parent.tsx b/app/web/src/nova/ed/panel/popup/script/scope/scope-parent.tsx index f6641843..baebb6cb 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/scope-parent.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/scope-parent.tsx @@ -1,5 +1,5 @@ import { IMeta, PG, active } from "../../../../logic/ed-global"; -import { addScope } from "./add-scope"; +import { extractExportImport } from "./extract-exim"; import { Monaco } from "./type"; export const defineScopeParent = (p: PG, meta: IMeta, monaco: Monaco) => { @@ -18,7 +18,12 @@ export const defineScopeParent = (p: PG, meta: IMeta, monaco: Monaco) => { } } + let i = 0; + let next_parent = parents[i + 1]; + const imports = {} as Record; for (const m of parents) { + next_parent = parents[i + 1]; + if (active.comp_id && m.parent?.id === "root" && active.instance) { const meta = p.page.meta[active.instance.item_id]; if (meta) { @@ -26,13 +31,15 @@ export const defineScopeParent = (p: PG, meta: IMeta, monaco: Monaco) => { m.scope.def.props = meta.scope?.def?.props; } } - + const def = m.scope.def; if (def) { - if (def.local) { - } else if (def.passprop) { - } else if (def.props) { + if (!imports[m.item.id]) imports[m.item.id] = []; + const res = extractExportImport(p, m, imports[m.item.id]); + if (next_parent) { + imports[next_parent.item.id] = res.imports; } } + i++; } }; diff --git a/app/web/src/nova/ed/panel/tree/search.tsx b/app/web/src/nova/ed/panel/tree/search.tsx index 029504bb..ca6a0082 100644 --- a/app/web/src/nova/ed/panel/tree/search.tsx +++ b/app/web/src/nova/ed/panel/tree/search.tsx @@ -36,7 +36,7 @@ export const EdTreeSearch = () => { >
{ local.sref = ref; }} @@ -117,7 +117,7 @@ export const doTreeSearch = (p: PG) => { let i = 0; let ptree = p.page.tree; - if (active.comp_id && p.comp.list[active.comp_id].tree) { + if (active.comp_id && p.comp.list[active.comp_id]?.tree) { ptree = p.comp.list[active.comp_id].tree; } diff --git a/app/web/src/nova/vi/load/load-legacy.tsx b/app/web/src/nova/vi/load/load-legacy.tsx index 8afacef8..3f1ffc9c 100644 --- a/app/web/src/nova/vi/load/load-legacy.tsx +++ b/app/web/src/nova/vi/load/load-legacy.tsx @@ -39,7 +39,13 @@ export const viLoadLegacy = async (vi: { let api_url = vi.site.api_url; if (!api_url) api_url = ((site.config as any) || {}).api_url || ""; - await loadApiProxyDef(api_url, true); + if (api_url) { + try { + await loadApiProxyDef(api_url, true); + } catch (e) { + console.warn("Failed to load API:", api_url); + } + } const path = `/npm/site/${vi.site.id}/site.js`; await importModule(path); diff --git a/app/web/tsconfig.json b/app/web/tsconfig.json index 194b8c52..46db205d 100644 --- a/app/web/tsconfig.json +++ b/app/web/tsconfig.json @@ -2,7 +2,12 @@ "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, - "lib": ["WebWorker", "DOM", "DOM.Iterable", "ESNext"], + "lib": [ + "WebWorker", + "DOM", + "DOM.Iterable", + "ESNext" + ], "allowJs": false, "skipLibCheck": false, "esModuleInterop": false, @@ -16,7 +21,12 @@ // "noEmit": true, "jsx": "react-jsx", "paths": { - "dbgen": ["../../node_modules/.prisma/client/index.d.ts"], - } + "dbgen": [ + "../../node_modules/.prisma/client/index.d.ts" + ], + }, + "types": [ + "bun-types" // add Bun global + ], } -} +} \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index f561bbb1..455ac6ce 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index b55e12c4..c2418b9e 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "dependencies": { "brotli-wasm": "^2.0.1", "fdir": "^6.1.0", + "react-select": "^5.8.0", "typescript": "^5.2.2" } } \ No newline at end of file diff --git a/pkgs/web-utils/src/hydrate-global.ts b/pkgs/web-utils/src/hydrate-global.ts new file mode 100644 index 00000000..2a087d6b --- /dev/null +++ b/pkgs/web-utils/src/hydrate-global.ts @@ -0,0 +1,9 @@ +const w = (typeof window !== "undefined" ? window : {}) as unknown as { + globalValueID?: WeakMap; +}; + +export const hydrateGlobal = ( + global_ref: any, + key: string, + initial_data: any +) => {};