fix
This commit is contained in:
parent
415f42cefc
commit
3cb7c393ec
|
|
@ -1,15 +1,19 @@
|
||||||
import { Websocket } from "hyper-express";
|
import { ServerWebSocket } from "bun";
|
||||||
import { compress } from "lz-string";
|
import { compress } from "lz-string";
|
||||||
import { syncronize } from "y-pojo";
|
import { syncronize } from "y-pojo";
|
||||||
import * as Y from "yjs";
|
import * as Y from "yjs";
|
||||||
|
import { WSData } from "../../../../../pkgs/core/server/create";
|
||||||
|
import { SingleComp, eg } from "../edit-global";
|
||||||
import {
|
import {
|
||||||
WS_MSG_GET_COMP,
|
WS_MSG_GET_COMP,
|
||||||
WS_MSG_SET_COMP,
|
WS_MSG_SET_COMP,
|
||||||
WS_MSG_SV_LOCAL,
|
WS_MSG_SV_LOCAL,
|
||||||
} from "../../../web/src/utils/types/ws";
|
} from "../../../../web/src/utils/types/ws";
|
||||||
import { SingleComp, eg } from "../edit-global";
|
|
||||||
|
|
||||||
export const getComp = async (ws: Websocket, msg: WS_MSG_GET_COMP) => {
|
export const getComp = async (
|
||||||
|
ws: ServerWebSocket<WSData>,
|
||||||
|
msg: WS_MSG_GET_COMP
|
||||||
|
) => {
|
||||||
const comp_id = msg.comp_id;
|
const comp_id = msg.comp_id;
|
||||||
|
|
||||||
if (!eg.edit.comp[comp_id]) {
|
if (!eg.edit.comp[comp_id]) {
|
||||||
|
|
@ -17,6 +21,15 @@ export const getComp = async (ws: Websocket, msg: WS_MSG_GET_COMP) => {
|
||||||
where: {
|
where: {
|
||||||
id: comp_id,
|
id: comp_id,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
component_group: true,
|
||||||
|
content_tree: true,
|
||||||
|
id: true,
|
||||||
|
id_component_group: true,
|
||||||
|
name: true,
|
||||||
|
props: true,
|
||||||
|
type: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!rawComp) {
|
if (!rawComp) {
|
||||||
|
|
@ -34,7 +47,7 @@ export const getComp = async (ws: Websocket, msg: WS_MSG_GET_COMP) => {
|
||||||
const map = ydoc.getMap("map");
|
const map = ydoc.getMap("map");
|
||||||
syncronize(map as any, rawComp);
|
syncronize(map as any, rawComp);
|
||||||
|
|
||||||
const ws = new Set<Websocket>();
|
const ws = new Set<ServerWebSocket<WSData>>();
|
||||||
const um = new Y.UndoManager(map, { ignoreRemoteMapChanges: true });
|
const um = new Y.UndoManager(map, { ignoreRemoteMapChanges: true });
|
||||||
const broadcast = () => {
|
const broadcast = () => {
|
||||||
const sv_local = compress(Y.encodeStateVector(ydoc as any).toString());
|
const sv_local = compress(Y.encodeStateVector(ydoc as any).toString());
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import { Websocket } from "hyper-express";
|
|
||||||
import { syncronize } from "y-pojo";
|
|
||||||
import * as Y from "yjs";
|
|
||||||
import { fillID } from "../../../web/src/utils/page/tools/fill-id";
|
|
||||||
import { IContent, MContent } from "../../../web/src/utils/types/general";
|
|
||||||
import { IItem } from "../../../web/src/utils/types/item";
|
|
||||||
import { IRoot } from "../../../web/src/utils/types/root";
|
|
||||||
import { getComp } from "../action/get-comp";
|
|
||||||
import { eg } from "../edit-global";
|
|
||||||
|
|
||||||
const MAX_STRING_LENGTH = 15000;
|
|
||||||
export const validateTreeMap = async (
|
|
||||||
ws: Websocket,
|
|
||||||
item: MContent,
|
|
||||||
changed?: boolean
|
|
||||||
) => {
|
|
||||||
let _changed = changed;
|
|
||||||
const type = item.get("type") as IContent["type"] | "root";
|
|
||||||
if (type !== "root") {
|
|
||||||
item.forEach((val, key, map) => {
|
|
||||||
if (typeof val === "string") {
|
|
||||||
if (val.length > MAX_STRING_LENGTH) {
|
|
||||||
map.set(key, "");
|
|
||||||
_changed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (typeof val === "object" && val instanceof Y.Map) {
|
|
||||||
val._map.forEach((ival, ikey, imap) => {
|
|
||||||
if (typeof ival === "string") {
|
|
||||||
if ((ival as string).length > MAX_STRING_LENGTH) {
|
|
||||||
imap.set(ikey, "" as any);
|
|
||||||
_changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
if (type !== "text") {
|
|
||||||
const childs = item.get("childs");
|
|
||||||
if (childs) {
|
|
||||||
for (const c of childs) {
|
|
||||||
if (await validateTreeMap(ws, c)) {
|
|
||||||
_changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !!_changed;
|
|
||||||
};
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
import { Suspense, lazy, useEffect } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { page, useLocal } from "web-utils";
|
import { page, useGlobal, useLocal } from "web-utils";
|
||||||
|
import { EditorGlobal } from "../../render/editor/logic/global";
|
||||||
import { Loading } from "../../utils/ui/loading";
|
import { Loading } from "../../utils/ui/loading";
|
||||||
|
|
||||||
const Editor = lazy(async () => ({
|
|
||||||
default: (await import("../../render/editor/editor")).Editor,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default page({
|
export default page({
|
||||||
url: "/editor/:site_id/:page_id",
|
url: "/editor/:site_id/:page_id",
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
|
const p = useGlobal(EditorGlobal, "EDITOR");
|
||||||
|
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
loading: true,
|
loading: true,
|
||||||
session: null as any,
|
session: null as any,
|
||||||
notfound: false,
|
notfound: false,
|
||||||
init: false,
|
init: false,
|
||||||
|
Editor: null as null | FC<any>,
|
||||||
});
|
});
|
||||||
const site_id = params.site_id === "_" ? "" : params.site_id;
|
const site_id = params.site_id === "_" ? "" : params.site_id;
|
||||||
const page_id = params.page_id === "_" ? "" : params.page_id;
|
const page_id = params.page_id === "_" ? "" : params.page_id;
|
||||||
|
|
@ -21,6 +21,10 @@ export default page({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!local.init) {
|
if (!local.init) {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
if (!local.Editor) {
|
||||||
|
local.Editor = (await import("../../render/editor/editor")).Editor;
|
||||||
|
}
|
||||||
|
|
||||||
let ses: any = null;
|
let ses: any = null;
|
||||||
try {
|
try {
|
||||||
ses = JSON.parse(localStorage.getItem("prasi-session") || "");
|
ses = JSON.parse(localStorage.getItem("prasi-session") || "");
|
||||||
|
|
@ -129,12 +133,11 @@ export default page({
|
||||||
}
|
}
|
||||||
}, [local.init]);
|
}, [local.init]);
|
||||||
|
|
||||||
if (local.loading) return <Loading note="base-page" />;
|
const Editor = local.Editor;
|
||||||
|
if (local.loading || !Editor) return <Loading note="base-page" />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<Loading note="editor-init" />}>
|
<Editor session={local.session} site_id={site_id} page_id={page_id} />
|
||||||
<Editor session={local.session} site_id={site_id} page_id={page_id} />
|
|
||||||
</Suspense>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export const Root: FC<{}> = ({}) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
prasiContext.render = local.render;
|
prasiContext.render = local.render;
|
||||||
|
|
||||||
const Provider = GlobalContext.Provider as FC<{ value: any; children: any }>;
|
const Provider = GlobalContext.Provider as FC<{ value: any; children: any }>;
|
||||||
|
|
||||||
const found = local.router.lookup(location.pathname);
|
const found = local.router.lookup(location.pathname);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export const Editor: FC<{ site_id: string; page_id: string; session: any }> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (p.status !== "init" && w.prasiApi) {
|
if (p.status !== "init" && w.prasiApi) {
|
||||||
for (const [k, v] of Object.entries(deepClone(EditorGlobal))) {
|
for (const [k, v] of Object.entries(deepClone(EditorGlobal))) {
|
||||||
if (k === "session" || k === "site") continue;
|
if (k === "session" || k === "site" || "status") continue;
|
||||||
(p as any)[k] = v;
|
(p as any)[k] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,6 +99,7 @@ export const Editor: FC<{ site_id: string; page_id: string; session: any }> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.status === "init") {
|
if (p.status === "init") {
|
||||||
|
(window as any).mok = ((window as any).mok || 0) + 1;
|
||||||
p.ui.loading = <Loading note="load-page" />;
|
p.ui.loading = <Loading note="load-page" />;
|
||||||
p.ui.preload = <Loading note="preload-root" backdrop={false} />;
|
p.ui.preload = <Loading note="preload-root" backdrop={false} />;
|
||||||
p.ui.notfound = (
|
p.ui.notfound = (
|
||||||
|
|
@ -109,6 +110,7 @@ export const Editor: FC<{ site_id: string; page_id: string; session: any }> = ({
|
||||||
PREVIEW ERROR
|
PREVIEW ERROR
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
p.status = "loading";
|
||||||
initEditor(p, site_id);
|
initEditor(p, site_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,119 +32,119 @@ export const w = window as unknown as {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initEditor = async (p: PG, site_id: string) => {
|
export const initEditor = async (p: PG, site_id: string) => {
|
||||||
if (p.status === "init") {
|
|
||||||
p.status = "loading";
|
|
||||||
|
|
||||||
w.isEditor = true;
|
w.isEditor = true;
|
||||||
if (typeof w.isLayout === "undefined") {
|
if (typeof w.isLayout === "undefined") {
|
||||||
w.isLayout = false;
|
w.isLayout = false;
|
||||||
}
|
}
|
||||||
w.isMobile = p.mode === "mobile";
|
w.isMobile = p.mode === "mobile";
|
||||||
w.isDesktop = p.mode === "desktop";
|
w.isDesktop = p.mode === "desktop";
|
||||||
w.apiHeaders = {};
|
w.apiHeaders = {};
|
||||||
w.preload = () => {};
|
w.preload = () => {};
|
||||||
|
|
||||||
w.navigateOverride = (_href) => {
|
w.navigateOverride = (_href) => {
|
||||||
if (_href.startsWith("/ed")) return _href;
|
if (_href.startsWith("/ed")) return _href;
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
p.item.active = localStorage.getItem("prasi-item-active-id") || "";
|
p.item.active = localStorage.getItem("prasi-item-active-id") || "";
|
||||||
p.item.activeOriginalId =
|
p.item.activeOriginalId = localStorage.getItem("prasi-item-active-oid") || "";
|
||||||
localStorage.getItem("prasi-item-active-oid") || "";
|
const comp: any = {
|
||||||
const comp: any = {
|
id: localStorage.getItem("prasi-comp-active-id"),
|
||||||
id: localStorage.getItem("prasi-comp-active-id"),
|
instance_id: localStorage.getItem("prasi-comp-instance-id"),
|
||||||
instance_id: localStorage.getItem("prasi-comp-instance-id"),
|
last: localStorage.getItem("prasi-comp-active-last"),
|
||||||
last: localStorage.getItem("prasi-comp-active-last"),
|
props: localStorage.getItem("prasi-comp-active-props"),
|
||||||
props: localStorage.getItem("prasi-comp-active-props"),
|
};
|
||||||
};
|
if (comp.last) {
|
||||||
if (comp.last) {
|
comp.last = JSON.parse(comp.last);
|
||||||
comp.last = JSON.parse(comp.last);
|
}
|
||||||
|
if (comp.props) {
|
||||||
|
comp.props = JSON.parse(comp.props);
|
||||||
|
}
|
||||||
|
if (comp.id) {
|
||||||
|
p.comp = comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
let site = null as any;
|
||||||
|
try {
|
||||||
|
site = JSON.parse(localStorage.getItem(`prasi-site-${site_id}`) || "");
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
const querySite = async () => {
|
||||||
|
const site = await defaultLoader.site(p as any, { id: site_id });
|
||||||
|
|
||||||
|
localStorage.setItem(`prasi-site-${site_id}`, JSON.stringify(site));
|
||||||
|
return site;
|
||||||
|
};
|
||||||
|
const processSite = async (site: LSite) => {
|
||||||
|
if (!w.exports) {
|
||||||
|
w.exports = {};
|
||||||
}
|
}
|
||||||
if (comp.props) {
|
if (site.cgroup_ids) {
|
||||||
comp.props = JSON.parse(comp.props);
|
for (const id of site.cgroup_ids) {
|
||||||
}
|
await importModule(`${serverurl}/npm/site/${id}/site.js`);
|
||||||
if (comp.id) {
|
}
|
||||||
p.comp = comp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let site = null as any;
|
await importModule(`${serverurl}/npm/site/${site.id}/site.js`);
|
||||||
try {
|
p.lsite = site;
|
||||||
site = JSON.parse(localStorage.getItem(`prasi-site-${site_id}`) || "");
|
p.site.id = site.id;
|
||||||
} catch (e) {}
|
p.site.js = site.js || "";
|
||||||
|
p.site.js_compiled = site.js_compiled || "";
|
||||||
|
p.site.name = site.name;
|
||||||
|
p.site.domain = site.domain;
|
||||||
|
p.site.responsive = site.responsive as any;
|
||||||
|
p.site.layout = site.layout;
|
||||||
|
p.site.layout_id = site.layout_id;
|
||||||
|
|
||||||
const querySite = async () => {
|
await validateLayout(p);
|
||||||
const site = await defaultLoader.site(p as any, { id: site_id });
|
|
||||||
localStorage.setItem(`prasi-site-${site_id}`, JSON.stringify(site));
|
w.externalAPI = {
|
||||||
return site;
|
mode: (localStorage.getItem(`prasi-ext-api-mode-${p.site.id}`) ||
|
||||||
|
"prod") as any,
|
||||||
|
devUrl: localStorage.getItem(`prasi-ext-dev-url-${p.site.id}`) || "",
|
||||||
|
prodUrl: localStorage.getItem(`prasi-ext-prod-url-${p.site.id}`) || "",
|
||||||
};
|
};
|
||||||
const processSite = async (site: LSite) => {
|
|
||||||
if (!w.exports) {
|
|
||||||
w.exports = {};
|
|
||||||
}
|
|
||||||
if (site.cgroup_ids) {
|
|
||||||
for (const id of site.cgroup_ids) {
|
|
||||||
await importModule(`${serverurl}/npm/site/${id}/site.js`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await importModule(`${serverurl}/npm/site/${site.id}/site.js`);
|
p.site.api_url = await initApi(site.config);
|
||||||
p.lsite = site;
|
|
||||||
p.site.id = site.id;
|
|
||||||
p.site.js = site.js || "";
|
|
||||||
p.site.js_compiled = site.js_compiled || "";
|
|
||||||
p.site.name = site.name;
|
|
||||||
p.site.domain = site.domain;
|
|
||||||
p.site.responsive = site.responsive as any;
|
|
||||||
p.site.layout = site.layout;
|
|
||||||
p.site.layout_id = site.layout_id;
|
|
||||||
|
|
||||||
await validateLayout(p);
|
if (w.externalAPI.prodUrl !== p.site.api_url) {
|
||||||
|
w.externalAPI.prodUrl = p.site.api_url;
|
||||||
|
localStorage.setItem(`prasi-ext-prod-url-${p.site.id}`, p.site.api_url);
|
||||||
|
}
|
||||||
|
if (w.externalAPI.mode === "dev" && w.externalAPI.devUrl) {
|
||||||
|
p.site.api_url = w.externalAPI.devUrl;
|
||||||
|
await reloadDBAPI(w.externalAPI.devUrl);
|
||||||
|
}
|
||||||
|
|
||||||
w.externalAPI = {
|
w.apiurl = p.site.api_url;
|
||||||
mode: (localStorage.getItem(`prasi-ext-api-mode-${p.site.id}`) ||
|
api.site_dts(p.site.id).then((e: any) => {
|
||||||
"prod") as any,
|
p.site_dts = e || "";
|
||||||
devUrl: localStorage.getItem(`prasi-ext-dev-url-${p.site.id}`) || "",
|
p.render();
|
||||||
prodUrl: localStorage.getItem(`prasi-ext-prod-url-${p.site.id}`) || "",
|
});
|
||||||
};
|
const configLocal: any = get(site, "config.prasi");
|
||||||
|
if (configLocal) {
|
||||||
|
p.site.api_prasi.db = configLocal.dburl ? configLocal.dburl : "";
|
||||||
|
p.site.api_prasi.port = configLocal.port ? configLocal.port : "";
|
||||||
|
}
|
||||||
|
execSiteJS(p);
|
||||||
|
};
|
||||||
|
|
||||||
p.site.api_url = await initApi(site.config);
|
if (!site || (site && !site.id)) {
|
||||||
|
const site = await querySite();
|
||||||
if (w.externalAPI.prodUrl !== p.site.api_url) {
|
if (site) {
|
||||||
w.externalAPI.prodUrl = p.site.api_url;
|
|
||||||
localStorage.setItem(`prasi-ext-prod-url-${p.site.id}`, p.site.api_url);
|
|
||||||
}
|
|
||||||
if (w.externalAPI.mode === "dev" && w.externalAPI.devUrl) {
|
|
||||||
p.site.api_url = w.externalAPI.devUrl;
|
|
||||||
await reloadDBAPI(w.externalAPI.devUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
w.apiurl = p.site.api_url;
|
|
||||||
api.site_dts(p.site.id).then((e) => {
|
|
||||||
p.site_dts = e || "";
|
|
||||||
p.render();
|
|
||||||
});
|
|
||||||
const configLocal: any = get(site, "config.prasi");
|
|
||||||
if (configLocal) {
|
|
||||||
p.site.api_prasi.db = configLocal.dburl ? configLocal.dburl : "";
|
|
||||||
p.site.api_prasi.port = configLocal.port ? configLocal.port : "";
|
|
||||||
}
|
|
||||||
execSiteJS(p);
|
|
||||||
};
|
|
||||||
if (!site || (site && !site.id)) {
|
|
||||||
const site = await querySite();
|
|
||||||
await processSite(site);
|
await processSite(site);
|
||||||
} else {
|
|
||||||
await processSite(site);
|
|
||||||
querySite();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await processSite(site);
|
||||||
|
querySite();
|
||||||
|
}
|
||||||
|
|
||||||
p.status = "ready";
|
p.status = "ready";
|
||||||
p.render();
|
p.render();
|
||||||
|
|
||||||
if (!jscript.build) {
|
if (!jscript.build) {
|
||||||
jscript.init();
|
jscript.init();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ export const defaultLoader: Loader = {
|
||||||
},
|
},
|
||||||
})) as unknown as LSite;
|
})) as unknown as LSite;
|
||||||
|
|
||||||
|
if (!site) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const cgroups = await db.site_use_comp.findMany({
|
const cgroups = await db.site_use_comp.findMany({
|
||||||
where: { id_site: site.id },
|
where: { id_site: site.id },
|
||||||
select: { use_id_site: true },
|
select: { use_id_site: true },
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,8 @@ export const liveWS = async (p: PG) => {
|
||||||
|
|
||||||
console.clear();
|
console.clear();
|
||||||
console.log(
|
console.log(
|
||||||
`🔥 Page updated: ${
|
`🔥 Page updated: ${p.page
|
||||||
p.page?.url
|
?.url} ${new Date().toLocaleString()}`
|
||||||
} ${new Date().toLocaleString()}`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -179,49 +178,6 @@ export const liveWS = async (p: PG) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "sitejs_reload":
|
|
||||||
if (msg.js) {
|
|
||||||
p.site.js = msg.js;
|
|
||||||
|
|
||||||
const exec = (fn: string, scopes: any) => {
|
|
||||||
if (p) {
|
|
||||||
if (!p.script.api) p.script.api = createAPI(p.site.api_url);
|
|
||||||
if (!p.script.db) p.script.db = createDB(p.site.api_url);
|
|
||||||
|
|
||||||
scopes["db"] = p.script.db;
|
|
||||||
scopes["api"] = p.script.api;
|
|
||||||
const f = new Function(...Object.keys(scopes), fn);
|
|
||||||
const res = f(...Object.values(scopes));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
const w = window as any;
|
|
||||||
const scope = {
|
|
||||||
types: {},
|
|
||||||
exports: w.exports,
|
|
||||||
load: importModule,
|
|
||||||
render: p.render,
|
|
||||||
module: {
|
|
||||||
exports: {} as any,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
p.status = "init";
|
|
||||||
console.log(
|
|
||||||
`🔥 Site JS Reloaded: ${new Date().toLocaleString()}`
|
|
||||||
);
|
|
||||||
exec(p.site.js, scope);
|
|
||||||
|
|
||||||
if (scope.module.exports) {
|
|
||||||
for (const [k, v] of Object.entries(scope.module.exports)) {
|
|
||||||
w.exports[k] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.render();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "undo":
|
case "undo":
|
||||||
case "redo":
|
case "redo":
|
||||||
case "new_comp":
|
case "new_comp":
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { dir } from "./dir";
|
||||||
import { g } from "./global";
|
import { g } from "./global";
|
||||||
import { spawn } from "bun";
|
import { spawn } from "bun";
|
||||||
|
|
||||||
|
const decoder = new TextDecoder();
|
||||||
export const parcelBuild = async () => {
|
export const parcelBuild = async () => {
|
||||||
await dirAsync("app/static");
|
await dirAsync("app/static");
|
||||||
const args = [
|
const args = [
|
||||||
|
|
@ -26,47 +27,54 @@ export const parcelBuild = async () => {
|
||||||
});
|
});
|
||||||
await parcel.exited;
|
await parcel.exited;
|
||||||
} else {
|
} else {
|
||||||
const parcel = spawn({
|
await new Promise<void>((resolve) => {
|
||||||
cmd: args,
|
const parcel = spawn({
|
||||||
cwd: dir.path("app/web"),
|
cmd: args,
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
cwd: dir.path("app/web"),
|
||||||
});
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
|
});
|
||||||
|
|
||||||
g.parcel = parcel;
|
g.parcel = parcel;
|
||||||
|
|
||||||
let output = true;
|
let output = true;
|
||||||
(async () => {
|
let decoded = false;
|
||||||
if (parcel.stdout) {
|
(async () => {
|
||||||
for await (const chunk of parcel.stdout) {
|
if (parcel.stdout) {
|
||||||
if (output) process.stdout.write(chunk);
|
for await (const chunk of parcel.stdout) {
|
||||||
|
if (!decoded && decoder.decode(chunk).includes("✨")) {
|
||||||
|
resolve();
|
||||||
|
decoded = true;
|
||||||
|
}
|
||||||
|
if (output) process.stdout.write(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})();
|
||||||
})();
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
if (parcel.stderr) {
|
if (parcel.stderr) {
|
||||||
for await (const chunk of parcel.stderr) {
|
for await (const chunk of parcel.stderr) {
|
||||||
if (output) process.stderr.write(chunk);
|
if (output) process.stderr.write(chunk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})();
|
||||||
})();
|
|
||||||
|
|
||||||
const cleanup = async () => {
|
const cleanup = async () => {
|
||||||
output = false;
|
output = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
process.on("SIGINT", async () => {
|
process.on("SIGINT", async () => {
|
||||||
await cleanup();
|
await cleanup();
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on("SIGTERM", async () => {
|
process.on("SIGTERM", async () => {
|
||||||
await cleanup();
|
await cleanup();
|
||||||
process.exit();
|
process.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on("beforeExit", async () => {
|
process.on("beforeExit", async () => {
|
||||||
await cleanup();
|
await cleanup();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ export const useGlobal = <T extends object>(
|
||||||
if (!_id) {
|
if (!_id) {
|
||||||
_id = "GLOBAL_DEFAULT";
|
_id = "GLOBAL_DEFAULT";
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctx = useContext(GlobalContext);
|
const ctx = useContext(GlobalContext);
|
||||||
const { global, render } = ctx;
|
const { global, render } = ctx;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue