This commit is contained in:
Rizky 2024-06-21 09:39:36 +07:00
parent b0b39767d5
commit d5a084a464
41 changed files with 299 additions and 258 deletions

View File

@ -1,14 +1,19 @@
FROM oven/bun:1.1.15-debian as base
WORKDIR /app/prasi/repo
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install git curl gnupg zip unzip -yq
RUN apt-get install build-essential gcc git curl gnupg zip unzip -yq
RUN git config --global --add safe.directory /app/prasi/repo
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -
RUN apt-get update
RUN apt-get install nodejs -yq
RUN npm i -g node-gyp-build-optional-packages node-gyp pnpm
RUN PATH="/usr/lib/node_modules/npm/bin:$PATH"
COPY dockerzip .
RUN unzip -o dockerzip
RUN bun install

View File

@ -223,7 +223,7 @@ export const _ = {
return await responseCompressed(
req,
JSON.stringify(
pages.map((e) => ({
pages.map((e: any) => ({
id: e.id,
url: e.url,
root: e.content_tree,

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@
"@paralleldrive/cuid2": "^2.2.2",
"@types/lodash.isequal": "^4.5.8",
"@types/mime-types": "^2.1.4",
"esbuild": "^0.20.2",
"esbuild": "^0.21.5",
"esbuild-clean-plugin": "^1.0.0",
"lodash.isequal": "^4.5.0",
"mime-types": "^2.1.35",

View File

@ -16,12 +16,12 @@ export const code = {
await ensureLib(root, id_site);
await ensureFiles(root, id_site);
await initFrontEnd(root, id_site);
await initServer(root, id_site);
await initTypings(root, id_site);
if (exists(dir.data(`${root}`))) {
await $`chmod -R 777 ${dir.data(`${root}`)}`;
}
// await initFrontEnd(root, id_site);
// await initServer(root, id_site);
// await initTypings(root, id_site);
// if (exists(dir.data(`${root}`))) {
// await $`chmod -R 777 ${dir.data(`${root}`)}`;
// }
},
path(
id_site: string,

View File

@ -1,19 +1,20 @@
import globalExternals from "@fal-works/esbuild-plugin-global-externals";
import style from "@hyrious/esbuild-plugin-style";
import { dir } from "dir";
import { BuildOptions, BuildResult, context, formatMessages } from "esbuild";
import { context, formatMessages } from "esbuild";
import { cleanPlugin } from "esbuild-clean-plugin";
import isEqual from "lodash.isequal";
import { appendFile } from "node:fs/promises";
import { code } from "../../code";
import { user } from "../../../entity/user";
import { conns } from "../../../entity/conn";
import { SyncType } from "../../../type";
import { sendWS } from "../../../sync-handler";
import { removeAsync } from "fs-jetpack";
import { watch } from "fs";
import { appendFile } from "node:fs/promises";
import { server } from "../../../editor/code/server-main";
import { conns } from "../../../entity/conn";
import { user } from "../../../entity/user";
import { sendWS } from "../../../sync-handler";
import { SyncType } from "../../../type";
import { code } from "../../code";
import { existsAsync } from "fs-jetpack";
const decoder = new TextDecoder();
const pending = {} as any;
export const initFrontEnd = async (
root: string,
id_site: string,
@ -22,6 +23,13 @@ export const initFrontEnd = async (
let existing = code.internal.frontend[id_site];
if (existing) {
if (existing.npm) {
if (pending[id_site]) return;
pending[id_site] = true;
await existing.npm;
delete pending[id_site];
delete existing.npm;
} else {
if (force) {
try {
existing.watch.close();
@ -32,6 +40,13 @@ export const initFrontEnd = async (
return;
}
}
} else {
if (
!(await existsAsync(code.path(id_site, "site", "src", "node_modules")))
) {
return;
}
}
try {
await isInstalling(id_site);
@ -114,12 +129,12 @@ export const initFrontEnd = async (
const srv = code.internal.server[id_site];
if (filename?.startsWith("node_modules")) return;
if (
(filename?.endsWith(".tsx") ||
filename?.endsWith(".tsx") ||
filename?.endsWith(".ts") ||
filename?.endsWith(".css") ||
filename?.endsWith(".html"))
filename?.endsWith(".html")
) {
if (typeof fe !== 'undefined' && !fe.rebuilding) {
if (typeof fe !== "undefined" && !fe.rebuilding) {
fe.rebuilding = true;
try {
await fe.ctx.rebuild();
@ -127,7 +142,7 @@ export const initFrontEnd = async (
fe.rebuilding = false;
}
if (typeof srv !== 'undefined' && !srv.rebuilding && srv.ctx) {
if (typeof srv !== "undefined" && !srv.rebuilding && srv.ctx) {
srv.rebuilding = true;
try {
await srv.ctx.rebuild();
@ -174,122 +189,122 @@ const isInstalling = async (id_site: string) => {
return false;
};
const readPackageJSON = async (id_site: string) => {
const file = Bun.file(code.path(id_site, "site", "src", "package.json"));
const deps = new Set<string>();
// const readPackageJSON = async (id_site: string) => {
// const file = Bun.file(code.path(id_site, "site", "src", "package.json"));
// const deps = new Set<string>();
if (await file.exists()) {
const json = await file.json();
// if (await file.exists()) {
// const json = await file.json();
if (json.dependencies) {
for (const k of Object.keys(json.dependencies)) {
deps.add(k);
}
}
// if (json.dependencies) {
// for (const k of Object.keys(json.dependencies)) {
// deps.add(k);
// }
// }
if (json.devDependencies) {
for (const k of Object.keys(json.devDependencies)) {
deps.add(k);
}
}
}
return deps;
};
// if (json.devDependencies) {
// for (const k of Object.keys(json.devDependencies)) {
// deps.add(k);
// }
// }
// }
// return deps;
// };
const installDeps = async (
root: string,
res: BuildResult<BuildOptions>,
id_site: string
) => {
const pkgjson = await readPackageJSON(id_site);
const imports = new Set<string>();
// const installDeps = async (
// root: string,
// res: BuildResult<BuildOptions>,
// id_site: string
// ) => {
// const pkgjson = await readPackageJSON(id_site);
// const imports = new Set<string>();
if (res.errors.length > 0) {
for (const err of res.errors) {
if (err.notes?.[0].text.startsWith("You can mark the path ")) {
let im = err.notes?.[0].text.split('"')[1];
// if (res.errors.length > 0) {
// for (const err of res.errors) {
// if (err.notes?.[0].text.startsWith("You can mark the path ")) {
// let im = err.notes?.[0].text.split('"')[1];
if (
!im.startsWith(".") &&
!im.startsWith("@/") &&
!im.startsWith("app") &&
!im.startsWith("lib") &&
!im.startsWith("server")
) {
const parts = im.split("/");
if (im.startsWith("@")) {
im = `${parts[0]}/${parts[1]}`;
} else {
im = parts[0];
}
imports.add(im);
}
}
}
}
// if (
// !im.startsWith(".") &&
// !im.startsWith("@/") &&
// !im.startsWith("app") &&
// !im.startsWith("lib") &&
// !im.startsWith("server")
// ) {
// const parts = im.split("/");
// if (im.startsWith("@")) {
// im = `${parts[0]}/${parts[1]}`;
// } else {
// im = parts[0];
// }
// imports.add(im);
// }
// }
// }
// }
if (res.metafile) {
for (const [_, file] of Object.entries(res.metafile?.inputs || {})) {
for (const im of file.imports) {
if (im.kind === "import-statement" && im.external) {
if (
!im.path.startsWith(".") &&
!im.path.startsWith("@/") &&
!im.path.startsWith("app") &&
!im.path.startsWith("lib") &&
!im.path.startsWith("server")
) {
const parts = im.path.split("/");
let src = im.path;
if (src.startsWith("@")) {
src = `${parts[0]}/${parts[1]}`;
} else {
src = parts[0];
}
// if (res.metafile) {
// for (const [_, file] of Object.entries(res.metafile?.inputs || {})) {
// for (const im of file.imports) {
// if (im.kind === "import-statement" && im.external) {
// if (
// !im.path.startsWith(".") &&
// !im.path.startsWith("@/") &&
// !im.path.startsWith("app") &&
// !im.path.startsWith("lib") &&
// !im.path.startsWith("server")
// ) {
// const parts = im.path.split("/");
// let src = im.path;
// if (src.startsWith("@")) {
// src = `${parts[0]}/${parts[1]}`;
// } else {
// src = parts[0];
// }
imports.add(src);
}
}
}
}
}
// imports.add(src);
// }
// }
// }
// }
// }
if (!isEqual(imports, pkgjson)) {
const pkgjson = Bun.file(code.path(id_site, "site", "src", "package.json"));
if (!(await pkgjson.exists())) {
await Bun.write(
pkgjson,
JSON.stringify({
name: id_site,
scripts: {
startup:
"ulimit -c 0; tailwindcss --watch -i ./app/css/global.css -o ./app/css/build.css --minify",
},
})
);
}
// if (!isEqual(imports, pkgjson)) {
// const pkgjson = Bun.file(code.path(id_site, "site", "src", "package.json"));
// if (!(await pkgjson.exists())) {
// await Bun.write(
// pkgjson,
// JSON.stringify({
// name: id_site,
// scripts: {
// startup:
// "ulimit -c 0; tailwindcss --watch -i ./app/css/global.css -o ./app/css/build.css --minify",
// },
// })
// );
// }
await codeError(
id_site,
"Installing dependencies:\n " + [...imports].join("\n ")
);
let proc = Bun.spawn([`npm`, `install`, ...imports], {
stdio: ["inherit", "pipe", "pipe"],
cwd: dir.data(root),
});
// await codeError(
// id_site,
// "Installing dependencies:\n " + [...imports].join("\n ")
// );
// let proc = Bun.spawn([`npm`, `install`, ...imports], {
// stdio: ["inherit", "pipe", "pipe"],
// cwd: dir.data(root),
// });
async function print(generator: ReadableStream<Uint8Array>, prefix: any) {
for await (let value of generator) {
const str = decoder.decode(value);
await codeError(id_site, `${prefix} ${str}`, true);
}
}
// async function print(generator: ReadableStream<Uint8Array>, prefix: any) {
// for await (let value of generator) {
// const str = decoder.decode(value);
// await codeError(id_site, `${prefix} ${str}`, true);
// }
// }
print(proc.stdout, "stdout:");
print(proc.stderr, "stderr:");
// print(proc.stdout, "stdout:");
// print(proc.stderr, "stderr:");
await proc.exited;
// await codeError(id_site, "");
return true;
}
};
// await proc.exited;
// // await codeError(id_site, "");
// return true;
// }
// };

View File

@ -40,20 +40,19 @@ export const initTypings = async (
code.internal.typings[id_site] = {
timeout: Date.now(),
watch: watch(typings_path),
spawn: null as any
// spawn: Bun.spawn({
// cmd: [
// ...`${dir.path(
// platform() === "win32"
// ? "node_modules/.bin/tsc.exe"
// : "node_modules/.bin/tsc"
// )} --watch --moduleResolution node --emitDeclarationOnly --outFile ../typings.d.ts --declaration --noEmit false`.split(
// " "
// ),
// ],
// cwd: dir.data(`/code/${id_site}/site/src`),
// stdio: [typings_log, typings_log, "ignore"],
// }),
spawn: Bun.spawn({
cmd: [
...`${dir.path(
platform() === "win32"
? "node_modules/.bin/tsc.exe"
: "node_modules/.bin/tsc"
)} --watch --moduleResolution node --emitDeclarationOnly --outFile ../typings.d.ts --declaration --noEmit false`.split(
" "
),
],
cwd: dir.data(`/code/${id_site}/site/src`),
stdio: [typings_log, typings_log, "ignore"],
}),
};
let timeout = null as any;
code.internal.typings[id_site].watch.on("change", (e, path) => {

View File

@ -11,14 +11,23 @@ export const codeInternal = {
get server() {
if (!g.prasi_code) g.prasi_code = {};
if (!g.prasi_code.server) g.prasi_code.server = {};
return g.prasi_code.server as Record<SITE_ID, { rebuilding: boolean; ts: number; ctx: BuildContext }>;
return g.prasi_code.server as Record<
SITE_ID,
{ rebuilding: boolean; ts: number; ctx: BuildContext }
>;
},
get frontend() {
if (!g.prasi_code) g.prasi_code = {};
if (!g.prasi_code.frontend) g.prasi_code.frontend = {};
return g.prasi_code.frontend as Record<
SITE_ID,
{ ctx: BuildContext; timeout: any, watch: FSWatcher, rebuilding: boolean }
{
ctx: BuildContext;
timeout: any;
watch: FSWatcher;
rebuilding: boolean;
npm?: Promise<void>;
}
>;
},
get typings() {

View File

@ -2,6 +2,8 @@ import { Glob } from "bun";
import { dir } from "dir";
import { dirAsync, exists, copyAsync } from "fs-jetpack";
import { dirname } from "path";
import { g } from "utils/global";
import { code } from "../code";
export const ensureFiles = async (path: string, id_site: string) => {
const _dir = dir.data(path);
@ -15,65 +17,6 @@ export const ensureFiles = async (path: string, id_site: string) => {
});
try {
const pkg = Bun.file(dir.data(`${path}/package.json`));
if (!(await pkg.exists())) {
await Bun.write(
pkg,
JSON.stringify({
name: "site-" + id_site,
scripts: {
startup:
"ulimit -c 0; tailwindcss --watch -i ./app/css/global.css -o ./app/css/build.css --minify",
},
dependencies: {},
})
);
const imports = [
"@floating-ui/react",
"@paralleldrive/cuid2",
"@radix-ui/react-dropdown-menu",
"@radix-ui/react-label",
"@radix-ui/react-navigation-menu",
"@radix-ui/react-popover",
"@radix-ui/react-slider",
"@radix-ui/react-slot",
"@radix-ui/react-switch",
"@radix-ui/react-tabs",
"@types/file-saver",
"@types/lodash.capitalize",
"@types/lodash.get",
"@types/react",
"@types/react-dom",
"any-date-parser",
"chart.js",
"class-variance-authority",
"clsx",
"date-fns",
"embla-carousel-react",
"exceljs",
"lodash.capitalize",
"lodash.get",
"lucide-react",
"next-themes",
"quill",
"react",
"react-arborist",
"react-chartjs-2",
"react-data-grid",
"react-day-picker",
"react-resizable-panels",
"sonner",
"tailwind-merge",
];
let proc = Bun.spawn([`npm`, `install`, ...imports], {
stdio: ["inherit", "pipe", "pipe"],
cwd: dir.data(path),
});
await proc.exited;
}
for await (const t of templates) {
const f = t.replaceAll("_", ".");
const to = dir.data(path + `/${f}`);
@ -85,6 +28,76 @@ export const ensureFiles = async (path: string, id_site: string) => {
await copyAsync(from, to);
}
}
const pkg = Bun.file(dir.data(`${path}/package.json`));
if (!code.internal.frontend[id_site]) {
code.internal.frontend[id_site] = {} as any;
}
if (!(await pkg.exists())) {
code.internal.frontend[id_site].npm = new Promise<void>(async (done) => {
await Bun.write(
pkg,
JSON.stringify({
name: "site-" + id_site,
scripts: {
startup:
"ulimit -c 0; tailwindcss --watch -i ./app/css/global.css -o ./app/css/build.css --minify",
},
dependencies: {
"@babel/runtime": "^7.24.6",
"@floating-ui/core": "^1.6.2",
"@floating-ui/react": "^0.26.16",
"@noble/hashes": "^1.4.0",
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-compose-refs": "^1.0.1",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@types/file-saver": "^2.0.7",
"@types/lodash.capitalize": "^4.2.9",
"@types/lodash.get": "^4.4.9",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"any-date-parser": "^1.5.4",
"chart.js": "^4.4.3",
"class-variance-authority": "^0.7.0",
clsx: "^2.1.1",
dayjs: "^1.11.11",
"embla-carousel-react": "^8.1.1",
exceljs: "^4.4.0",
"lodash.capitalize": "^4.2.1",
"lodash.get": "^4.4.2",
"lucide-react": "^0.378.0",
"next-themes": "^0.3.0",
quill: "^2.0.2",
"quill-delta": "^5.1.0",
react: "^18.3.1",
"react-arborist": "^3.4.0",
"react-chartjs-2": "^5.2.0",
"react-data-grid": "^7.0.0-beta.44",
"react-day-picker": "^8.10.1",
"react-resizable-panels": "^2.0.19",
sonner: "^1.4.41",
tabbable: "^6.2.0",
"tailwind-merge": "^2.3.0",
xlsx: "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
},
})
);
let proc = Bun.spawn([`npm`, `install`], {
stdio: ["inherit", "inherit", "inherit"],
cwd: dir.data(path),
});
await proc.exited;
done();
});
}
} catch (e) {
console.log("error ensure file", e);
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -27,7 +27,7 @@
"date-fns": "^2.30.0",
"safe-flat": "^2.1.0",
"dbgen": "workspace:*",
"esbuild-wasm": "^0.19.10",
"esbuild-wasm": "^0.21.5",
"hash-wasm": "^4.11.0",
"idb-keyval": "^6.2.1",
"immer": "^10.0.3",

BIN
bun.lockb

Binary file not shown.

BIN
dockerzip

Binary file not shown.

View File

@ -19,7 +19,7 @@
"pkgs/*"
],
"dependencies": {
"brotli-wasm": "^2.0.1",
"brotli-wasm": "^3.0.1",
"fdir": "^6.1.0",
"react-select": "^5.8.0",
"typescript": "^5.2.2"

View File

@ -7,8 +7,8 @@
"woodpile": "^0.0.5",
"@types/mime": "^3.0.3",
"@types/unzipper": "^0.10.8",
"esbuild": "^0.20.2",
"brotli-wasm": "^2.0.1",
"esbuild": "^0.21.5",
"brotli-wasm": "^3.0.1",
"execa": "^8.0.1",
"fs-jetpack": "^5.1.0",
"lmdb": "^2.8.5",