@nyte-ai/host 0.0.0-stage → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +6 -2
- package/THIRD-PARTY-NOTICES.md +800 -0
- package/dist/chunks/canvas-preview-0cmbkp2j.js +65 -0
- package/dist/chunks/canvas-preview-0nq75h9k.js +7 -0
- package/dist/chunks/canvas-preview-0nrnbt76.js +497 -0
- package/dist/chunks/canvas-preview-1sq7z9jq.js +17 -0
- package/dist/chunks/canvas-preview-1ta3avah.js +56 -0
- package/dist/chunks/canvas-preview-2zdyh9ny.js +26 -0
- package/dist/chunks/canvas-preview-31w7xm8z.js +34 -0
- package/dist/chunks/canvas-preview-4b6sayhg.js +295 -0
- package/dist/chunks/canvas-preview-4e0pxa32.js +63 -0
- package/dist/chunks/canvas-preview-518dh8by.js +169 -0
- package/dist/chunks/canvas-preview-5hxat7hh.js +239 -0
- package/dist/chunks/canvas-preview-5mex725c.js +14 -0
- package/dist/chunks/canvas-preview-5z63am63.js +295 -0
- package/dist/chunks/canvas-preview-65xqjw7f.js +20 -0
- package/dist/chunks/canvas-preview-69fkk9yn.js +95 -0
- package/dist/chunks/canvas-preview-75db60xy.js +457 -0
- package/dist/chunks/canvas-preview-76fwvd6e.js +272 -0
- package/dist/chunks/canvas-preview-8xgt67ka.js +598 -0
- package/dist/chunks/canvas-preview-98aj5p34.js +176 -0
- package/dist/chunks/canvas-preview-9aqczacs.js +73 -0
- package/dist/chunks/canvas-preview-a3yw0j70.js +72 -0
- package/dist/chunks/canvas-preview-azg56359.js +68 -0
- package/dist/chunks/canvas-preview-d9wwhbtz.js +240 -0
- package/dist/chunks/canvas-preview-ehf3vp31.js +411 -0
- package/dist/chunks/canvas-preview-evh92ywd.js +369 -0
- package/dist/chunks/canvas-preview-ewgspmsd.js +81 -0
- package/dist/chunks/canvas-preview-g3qj3y3k.js +156 -0
- package/dist/chunks/canvas-preview-h8hshnff.js +63 -0
- package/dist/chunks/canvas-preview-j1tnf51w.js +36 -0
- package/dist/chunks/canvas-preview-kdqgrstc.js +194 -0
- package/dist/chunks/canvas-preview-kn7kvbfj.js +12 -0
- package/dist/chunks/canvas-preview-m02v4yy6.js +386 -0
- package/dist/chunks/canvas-preview-mgcx2b2p.js +271 -0
- package/dist/chunks/canvas-preview-rp4x6y1h.js +144 -0
- package/dist/chunks/canvas-preview-rp6fz0w5.js +130 -0
- package/dist/chunks/canvas-preview-s94ebwf5.js +112 -0
- package/dist/chunks/canvas-preview-senpjwep.js +518 -0
- package/dist/chunks/canvas-preview-skzwvw4d.js +23 -0
- package/dist/chunks/canvas-preview-srgfpdmf.js +60 -0
- package/dist/chunks/canvas-preview-tjhabynd.js +252 -0
- package/dist/chunks/canvas-preview-vaatfznm.js +189 -0
- package/dist/chunks/canvas-preview-vax9ne4e.js +341 -0
- package/dist/chunks/canvas-preview-wg80rbc2.js +46 -0
- package/dist/chunks/canvas-preview-xn10d4f8.js +608 -0
- package/dist/chunks/canvas-preview-yjz0f7n4.js +50 -0
- package/dist/chunks/canvas-preview-ymgz0937.js +587 -0
- package/dist/chunks/canvas-preview-yrfz2ak6.js +134 -0
- package/dist/chunks/canvas-preview-zaaj99wd.js +244 -0
- package/dist/chunks/canvas-preview-zn2d0k9d.js +133 -0
- package/dist/src/canvas-preview.d.ts +29 -0
- package/dist/src/canvas-preview.js +267 -0
- package/dist/src/credentials.d.ts +44 -0
- package/dist/src/credentials.js +10 -0
- package/dist/src/deploy/cloudflare/worker.d.ts +50 -0
- package/dist/src/deploy/cloudflare/worker.js +196 -0
- package/dist/src/deploy/vercel/nitro.config.d.ts +2 -0
- package/dist/src/deploy/vercel/nitro.config.js +30 -0
- package/dist/src/deploy/vercel/server/routes/[...].d.ts +2 -0
- package/dist/src/deploy/vercel/server/routes/[...].js +18 -0
- package/dist/src/deploy/vercel/server/utils/host.d.ts +13 -0
- package/dist/src/deploy/vercel/server/utils/host.js +7 -0
- package/dist/src/deploy/vercel/server/utils/repair.d.ts +1 -0
- package/dist/src/deploy/vercel/server/utils/repair.js +6 -0
- package/dist/src/deploy/vercel/server/utils/step.d.ts +10 -0
- package/dist/src/deploy/vercel/server/utils/step.js +6 -0
- package/dist/src/deploy/vercel/server/workflows/drive.d.ts +14 -0
- package/dist/src/deploy/vercel/server/workflows/drive.js +13 -0
- package/dist/src/durable-object.d.ts +14 -0
- package/dist/src/durable-object.js +231 -0
- package/dist/src/hash.d.ts +1 -0
- package/dist/src/hash.js +6 -0
- package/dist/src/identity-key.d.ts +11 -0
- package/dist/src/identity-key.js +9 -0
- package/dist/src/identity.d.ts +12 -0
- package/dist/src/identity.js +6 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.js +120 -0
- package/dist/src/key-file.d.ts +1 -0
- package/dist/src/key-file.js +7 -0
- package/dist/src/listen-fetch.d.ts +8 -0
- package/dist/src/listen-fetch.js +9 -0
- package/dist/src/listen.d.ts +4 -0
- package/dist/src/listen.js +10 -0
- package/dist/src/local/command.d.ts +15 -0
- package/dist/src/local/command.js +8 -0
- package/dist/src/local/feed.d.ts +7 -0
- package/dist/src/local/feed.js +6 -0
- package/dist/src/local/files.d.ts +18 -0
- package/dist/src/local/files.js +13 -0
- package/dist/src/local/git-watch.d.ts +15 -0
- package/dist/src/local/git-watch.js +7 -0
- package/dist/src/local/git.d.ts +5 -0
- package/dist/src/local/git.js +13 -0
- package/dist/src/local/github.d.ts +30 -0
- package/dist/src/local/github.js +9 -0
- package/dist/src/local/identity.d.ts +3 -0
- package/dist/src/local/identity.js +7 -0
- package/dist/src/local/jobs.d.ts +7 -0
- package/dist/src/local/jobs.js +6 -0
- package/dist/src/local/legacy-trust.d.ts +10 -0
- package/dist/src/local/legacy-trust.js +6 -0
- package/dist/src/local/patch.d.ts +16 -0
- package/dist/src/local/patch.js +17 -0
- package/dist/src/local/provider.d.ts +11 -0
- package/dist/src/local/provider.js +20 -0
- package/dist/src/local/snapshots.d.ts +7 -0
- package/dist/src/local/snapshots.js +11 -0
- package/dist/src/local/text.d.ts +1 -0
- package/dist/src/local/text.js +6 -0
- package/dist/src/local/tree.d.ts +50 -0
- package/dist/src/local/tree.js +16 -0
- package/dist/src/local/workspace-migration.d.ts +2 -0
- package/dist/src/local/workspace-migration.js +7 -0
- package/dist/src/local/worktrees.d.ts +46 -0
- package/dist/src/local/worktrees.js +14 -0
- package/dist/src/mcp/config.d.ts +75 -0
- package/dist/src/mcp/config.js +12 -0
- package/dist/src/mcp/connect.d.ts +28 -0
- package/dist/src/mcp/connect.js +9 -0
- package/dist/src/mcp/hub.d.ts +19 -0
- package/dist/src/mcp/hub.js +11 -0
- package/dist/src/mcp/oauth.d.ts +46 -0
- package/dist/src/mcp/oauth.js +12 -0
- package/dist/src/mcp/tools.d.ts +29 -0
- package/dist/src/mcp/tools.js +12 -0
- package/dist/src/open.d.ts +42 -0
- package/dist/src/open.js +44 -0
- package/dist/src/plugins/loader.d.ts +21 -0
- package/dist/src/plugins/loader.js +11 -0
- package/dist/src/postgres.d.ts +19 -0
- package/dist/src/postgres.js +8 -0
- package/dist/src/providers.d.ts +16 -0
- package/dist/src/providers.js +112 -0
- package/dist/src/secrets.d.ts +12 -0
- package/dist/src/secrets.js +8 -0
- package/dist/src/serve/binding.d.ts +39 -0
- package/dist/src/serve/binding.js +6 -0
- package/dist/src/serve/handler.d.ts +15 -0
- package/dist/src/serve/handler.js +8 -0
- package/dist/src/serve/stream-server.d.ts +6 -0
- package/dist/src/serve/stream-server.js +6 -0
- package/dist/src/session-index.d.ts +11 -0
- package/dist/src/session-index.js +11 -0
- package/dist/src/shell-env.d.ts +14 -0
- package/dist/src/shell-env.js +108 -0
- package/dist/src/sqlite-workers.d.ts +6 -0
- package/dist/src/sqlite-workers.js +6 -0
- package/dist/src/sqlite.d.ts +7 -0
- package/dist/src/sqlite.js +10 -0
- package/dist/src/store-owner.d.ts +15 -0
- package/dist/src/store-owner.js +9 -0
- package/dist/src/store-rows.d.ts +13 -0
- package/dist/src/store-rows.js +26 -0
- package/dist/src/store-usage.d.ts +25 -0
- package/dist/src/store-usage.js +16 -0
- package/dist/src/usage-scan.d.ts +24 -0
- package/dist/src/usage-scan.js +65 -0
- package/dist/src/usage-service.d.ts +22 -0
- package/dist/src/usage-service.js +12 -0
- package/dist/src/usage-summary.d.ts +9 -0
- package/dist/src/usage-summary.js +16 -0
- package/dist/src/usage-types.d.ts +86 -0
- package/dist/src/usage-types.js +0 -0
- package/dist/src/usage-worker.d.ts +1 -0
- package/dist/src/usage-worker.js +25 -0
- package/dist/src/usage.d.ts +72 -0
- package/dist/src/usage.js +13 -0
- package/package.json +132 -3
- package/src/canvas-preview.ts +402 -0
- package/src/credentials.ts +294 -0
- package/src/deploy/cloudflare/README.md +3 -0
- package/src/deploy/cloudflare/worker.ts +306 -0
- package/src/deploy/cloudflare/wrangler.jsonc +12 -0
- package/src/deploy/vercel/README.md +3 -0
- package/src/deploy/vercel/nitro.config.ts +29 -0
- package/src/deploy/vercel/server/routes/[...].ts +10 -0
- package/src/deploy/vercel/server/utils/host.ts +104 -0
- package/src/deploy/vercel/server/utils/repair.ts +35 -0
- package/src/deploy/vercel/server/utils/step.ts +25 -0
- package/src/deploy/vercel/server/workflows/drive.ts +46 -0
- package/src/deploy/vercel/tsconfig.json +9 -0
- package/src/deploy/vercel/types/bun.d.ts +2 -0
- package/src/durable-object.ts +386 -0
- package/src/hash.ts +5 -0
- package/src/identity-key.ts +20 -0
- package/src/identity.ts +66 -0
- package/src/index.ts +21 -0
- package/src/key-file.ts +53 -0
- package/src/listen-fetch.ts +409 -0
- package/src/listen.ts +228 -0
- package/src/local/command.ts +109 -0
- package/src/local/feed.ts +70 -0
- package/src/local/files.ts +812 -0
- package/src/local/git-watch.ts +189 -0
- package/src/local/git.ts +914 -0
- package/src/local/github.ts +692 -0
- package/src/local/identity.ts +21 -0
- package/src/local/jobs.ts +587 -0
- package/src/local/legacy-trust.ts +105 -0
- package/src/local/patch.ts +334 -0
- package/src/local/provider.ts +184 -0
- package/src/local/snapshots.ts +776 -0
- package/src/local/text.ts +9 -0
- package/src/local/tree.ts +398 -0
- package/src/local/workspace-migration.ts +95 -0
- package/src/local/worktrees.ts +239 -0
- package/src/mcp/config.ts +330 -0
- package/src/mcp/connect.ts +105 -0
- package/src/mcp/hub.ts +836 -0
- package/src/mcp/oauth.ts +436 -0
- package/src/mcp/tools.ts +333 -0
- package/src/open.ts +469 -0
- package/src/plugins/loader.ts +186 -0
- package/src/postgres.ts +492 -0
- package/src/providers.ts +135 -0
- package/src/secrets.ts +31 -0
- package/src/serve/binding.ts +628 -0
- package/src/serve/handler.ts +362 -0
- package/src/serve/stream-server.ts +176 -0
- package/src/session-index.ts +99 -0
- package/src/shell-env.ts +153 -0
- package/src/sqlite-workers.ts +283 -0
- package/src/sqlite.ts +528 -0
- package/src/store-owner.ts +98 -0
- package/src/store-rows.ts +110 -0
- package/src/store-usage.ts +344 -0
- package/src/usage-scan.ts +81 -0
- package/src/usage-service.ts +73 -0
- package/src/usage-summary.ts +79 -0
- package/src/usage-types.ts +87 -0
- package/src/usage-worker.ts +24 -0
- package/src/usage.ts +701 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {
|
|
2
|
+
sha2562
|
|
3
|
+
} from "./canvas-preview-0nq75h9k.js";
|
|
4
|
+
import {
|
|
5
|
+
localFiles2
|
|
6
|
+
} from "./canvas-preview-ymgz0937.js";
|
|
7
|
+
import {
|
|
8
|
+
localGit2
|
|
9
|
+
} from "./canvas-preview-xn10d4f8.js";
|
|
10
|
+
import {
|
|
11
|
+
localGitHub2
|
|
12
|
+
} from "./canvas-preview-75db60xy.js";
|
|
13
|
+
import {
|
|
14
|
+
folderIdentity2
|
|
15
|
+
} from "./canvas-preview-1sq7z9jq.js";
|
|
16
|
+
import {
|
|
17
|
+
localExec2
|
|
18
|
+
} from "./canvas-preview-ehf3vp31.js";
|
|
19
|
+
import {
|
|
20
|
+
localSnapshots2
|
|
21
|
+
} from "./canvas-preview-senpjwep.js";
|
|
22
|
+
import {
|
|
23
|
+
localWorktrees2
|
|
24
|
+
} from "./canvas-preview-rp6fz0w5.js";
|
|
25
|
+
|
|
26
|
+
// src/local/provider.ts
|
|
27
|
+
import { constants, realpathSync } from "node:fs";
|
|
28
|
+
import { access, readdir, realpath, stat } from "node:fs/promises";
|
|
29
|
+
import { homedir } from "node:os";
|
|
30
|
+
import { isAbsolute, join, relative, sep } from "node:path";
|
|
31
|
+
import { asId, SdkError } from "@nyte-ai/schema";
|
|
32
|
+
var PLUGIN_FILE = /\.(?:ts|mts|js|mjs)$/;
|
|
33
|
+
var ROOT_SOURCES = [".nyte/SYSTEM.md", ".nyte/APPEND_SYSTEM.md", ".nyte/mcp.json"];
|
|
34
|
+
function localProvider2(options) {
|
|
35
|
+
const home = options?.home ?? homedir();
|
|
36
|
+
const store = join(home, ".nyte", "snapshots");
|
|
37
|
+
let state;
|
|
38
|
+
const github = localGitHub2({ gh: options?.gh, git: options?.git });
|
|
39
|
+
return {
|
|
40
|
+
kind: "local",
|
|
41
|
+
async inspect(target) {
|
|
42
|
+
const path = readTargetPath(target);
|
|
43
|
+
if (path === null)
|
|
44
|
+
return {
|
|
45
|
+
identity: asId(sha2562(JSON.stringify(target))),
|
|
46
|
+
availability: { kind: "unavailable", reason: "unsupported" },
|
|
47
|
+
projectSources: []
|
|
48
|
+
};
|
|
49
|
+
const identity = await folderIdentity2(path);
|
|
50
|
+
if (!await readableDirectory(path))
|
|
51
|
+
return {
|
|
52
|
+
identity,
|
|
53
|
+
availability: { kind: "unavailable", reason: "unreachable" },
|
|
54
|
+
projectSources: []
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
identity,
|
|
58
|
+
availability: { kind: "available" },
|
|
59
|
+
projectSources: await projectSources(path)
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
async attach(target) {
|
|
63
|
+
const path = readTargetPath(target);
|
|
64
|
+
if (path === null)
|
|
65
|
+
throw new SdkError("unavailable", "A local workspace needs a path.");
|
|
66
|
+
const real = await realpath(path).catch(() => null);
|
|
67
|
+
if (real === null || !await readableDirectory(real))
|
|
68
|
+
throw new SdkError("unavailable", `${path} is not a readable directory.`);
|
|
69
|
+
const detached = new AbortController;
|
|
70
|
+
const env = {
|
|
71
|
+
identity: await folderIdentity2(real),
|
|
72
|
+
cwd: real,
|
|
73
|
+
files: localFiles2(real, {
|
|
74
|
+
ripgrep: options?.ripgrep,
|
|
75
|
+
formatter: options?.formatter,
|
|
76
|
+
signal: detached.signal
|
|
77
|
+
}),
|
|
78
|
+
exec: localExec2(real, { shell: options?.shell, signal: detached.signal }),
|
|
79
|
+
close: async () => detached.abort()
|
|
80
|
+
};
|
|
81
|
+
return env;
|
|
82
|
+
},
|
|
83
|
+
git: (env) => localGit2(env, { git: options?.git }),
|
|
84
|
+
github,
|
|
85
|
+
snapshots(env) {
|
|
86
|
+
state ??= join(realpathOrSelf(home), ".nyte");
|
|
87
|
+
return nests(env.cwd, state) || nests(state, env.cwd) && !nests(join(state, "worktrees"), env.cwd) ? undefined : localSnapshots2(env, { store, git: options?.git });
|
|
88
|
+
},
|
|
89
|
+
worktrees: localWorktrees2({ home, git: options?.git }),
|
|
90
|
+
async destroy() {
|
|
91
|
+
throw new SdkError("unavailable", "A local folder is never torn down.");
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function realpathOrSelf(path) {
|
|
96
|
+
try {
|
|
97
|
+
return realpathSync(path);
|
|
98
|
+
} catch {
|
|
99
|
+
return path;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function nests(outer, inner) {
|
|
103
|
+
const path = relative(outer, inner);
|
|
104
|
+
return path === "" || path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
|
|
105
|
+
}
|
|
106
|
+
function readTargetPath(target) {
|
|
107
|
+
return "path" in target && typeof target.path === "string" ? target.path : null;
|
|
108
|
+
}
|
|
109
|
+
async function readableDirectory(path) {
|
|
110
|
+
const stats = await stat(path).catch(() => null);
|
|
111
|
+
return stats !== null && stats.isDirectory() && await access(path, constants.R_OK | constants.X_OK).then(() => true, () => false);
|
|
112
|
+
}
|
|
113
|
+
async function projectSources(root) {
|
|
114
|
+
const names = async (directory) => (await readdir(join(root, directory)).catch(() => [])).sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
|
|
115
|
+
const fileExists = async (path) => (await stat(join(root, path)).catch(() => null))?.isFile() === true;
|
|
116
|
+
const plugins = (await Promise.all((await names(".nyte/plugins")).map(async (name) => {
|
|
117
|
+
const path = `.nyte/plugins/${name}`;
|
|
118
|
+
if (PLUGIN_FILE.test(name) && await fileExists(path))
|
|
119
|
+
return [path];
|
|
120
|
+
for (const index of ["index.ts", "index.mts", "index.js", "index.mjs"])
|
|
121
|
+
if (await fileExists(`${path}/${index}`))
|
|
122
|
+
return [`${path}/${index}`];
|
|
123
|
+
return [];
|
|
124
|
+
}))).flat();
|
|
125
|
+
const skills = (await Promise.all([".nyte/skills", ".agents/skills"].map(async (directory) => (await Promise.all((await names(directory)).map(async (name) => {
|
|
126
|
+
const path = `${directory}/${name}/SKILL.md`;
|
|
127
|
+
return await fileExists(path) ? [path] : [];
|
|
128
|
+
}))).flat()))).flat();
|
|
129
|
+
const prompts = (await names(".nyte/prompts")).filter((name) => name.endsWith(".md")).map((name) => `.nyte/prompts/${name}`);
|
|
130
|
+
const present = await Promise.all(ROOT_SOURCES.map(async (path) => await fileExists(path) ? [path] : []));
|
|
131
|
+
return [...plugins, ...skills, ...prompts, ...present.flat()];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { localProvider2 };
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// src/sqlite-workers.ts
|
|
2
|
+
import { Worker } from "node:worker_threads";
|
|
3
|
+
import { dev } from "@nyte-ai/core";
|
|
4
|
+
import { Type } from "typebox";
|
|
5
|
+
import { Value } from "typebox/value";
|
|
6
|
+
var rowSchema = Type.Record(Type.String(), Type.Union([Type.Null(), Type.String(), Type.Number(), Type.BigInt()]));
|
|
7
|
+
var replySchema = Type.Union([
|
|
8
|
+
Type.Object({ ready: Type.Literal(true) }),
|
|
9
|
+
Type.Object({ id: Type.Integer(), rows: Type.Array(rowSchema), executionMs: Type.Number() }),
|
|
10
|
+
Type.Object({
|
|
11
|
+
id: Type.Integer(),
|
|
12
|
+
error: Type.String(),
|
|
13
|
+
code: Type.Optional(Type.String()),
|
|
14
|
+
errcode: Type.Optional(Type.Number()),
|
|
15
|
+
errstr: Type.Optional(Type.String())
|
|
16
|
+
})
|
|
17
|
+
]);
|
|
18
|
+
var source = String.raw`
|
|
19
|
+
const { parentPort, workerData } = require("node:worker_threads");
|
|
20
|
+
const { DatabaseSync } = require("node:sqlite");
|
|
21
|
+
const db = new DatabaseSync(workerData.path, {
|
|
22
|
+
readOnly: workerData.role === "reader",
|
|
23
|
+
timeout: 5000,
|
|
24
|
+
});
|
|
25
|
+
if (String(db.prepare("PRAGMA journal_mode").get().journal_mode).toLowerCase() !== "wal")
|
|
26
|
+
throw new Error("SQLite workers require WAL mode");
|
|
27
|
+
if (workerData.role === "checkpoint") {
|
|
28
|
+
const version = db.prepare("SELECT sqlite_version() AS version").get().version;
|
|
29
|
+
const [major, minor] = version.split(".").map(Number);
|
|
30
|
+
if (major < 3 || (major === 3 && minor < 51))
|
|
31
|
+
throw new Error("SQLite " + version + " has no NOOP checkpoint");
|
|
32
|
+
db.exec("PRAGMA synchronous = NORMAL; PRAGMA checkpoint_fullfsync = ON");
|
|
33
|
+
}
|
|
34
|
+
const statements = new Map();
|
|
35
|
+
const frames = workerData.role === "checkpoint" ? db.prepare("PRAGMA wal_checkpoint(NOOP)") : null;
|
|
36
|
+
const checkpoint = workerData.role === "checkpoint" ? db.prepare("PRAGMA wal_checkpoint(PASSIVE)") : null;
|
|
37
|
+
let idle;
|
|
38
|
+
parentPort.on("message", ({ id, sql, params }) => {
|
|
39
|
+
const started = performance.now();
|
|
40
|
+
try {
|
|
41
|
+
let rows = [];
|
|
42
|
+
if (workerData.role === "checkpoint") {
|
|
43
|
+
const { log, checkpointed } = frames.get();
|
|
44
|
+
if (log - checkpointed >= 1000) checkpoint.get();
|
|
45
|
+
clearTimeout(idle);
|
|
46
|
+
idle = setTimeout(() => {
|
|
47
|
+
const { log, checkpointed } = frames.get();
|
|
48
|
+
if (log >= 1000 && checkpointed < log) checkpoint.get();
|
|
49
|
+
}, 100);
|
|
50
|
+
} else {
|
|
51
|
+
const size = params.reduce((total, value) => total + (typeof value === "string" ? value.length : ArrayBuffer.isView(value) ? value.byteLength : 0), 0);
|
|
52
|
+
let statement = size > 65536 ? undefined : statements.get(sql);
|
|
53
|
+
if (statement === undefined) {
|
|
54
|
+
statement = db.prepare(sql);
|
|
55
|
+
if (size <= 65536) {
|
|
56
|
+
if (statements.size >= 16) statements.delete(statements.keys().next().value);
|
|
57
|
+
statements.set(sql, statement);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
rows = statement.all(...params);
|
|
61
|
+
}
|
|
62
|
+
parentPort.postMessage({ id, rows, executionMs: performance.now() - started });
|
|
63
|
+
} catch (error) {
|
|
64
|
+
parentPort.postMessage({ id, error: String(error.message), code: error.code, errcode: error.errcode, errstr: error.errstr });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
parentPort.postMessage({ ready: true });
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
class SqliteWorker {
|
|
71
|
+
ready;
|
|
72
|
+
worker;
|
|
73
|
+
nextId = 0;
|
|
74
|
+
pending = new Map;
|
|
75
|
+
stop;
|
|
76
|
+
constructor(path, role, unavailable) {
|
|
77
|
+
const worker = new Worker(source, { eval: true, workerData: { path, role } });
|
|
78
|
+
this.worker = worker;
|
|
79
|
+
let started = false;
|
|
80
|
+
let announce = () => {
|
|
81
|
+
return;
|
|
82
|
+
};
|
|
83
|
+
this.ready = new Promise((resolve) => {
|
|
84
|
+
announce = resolve;
|
|
85
|
+
});
|
|
86
|
+
const timeout = setTimeout(() => {
|
|
87
|
+
this.stop(new Error("SQLite worker did not start within 10 seconds"), true);
|
|
88
|
+
}, 1e4);
|
|
89
|
+
timeout.unref();
|
|
90
|
+
this.stop = (cause, notify) => {
|
|
91
|
+
if (this.worker === null)
|
|
92
|
+
return;
|
|
93
|
+
this.worker = null;
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
announce(false);
|
|
96
|
+
for (const request of this.pending.values())
|
|
97
|
+
request.reject(cause);
|
|
98
|
+
this.pending.clear();
|
|
99
|
+
if (notify)
|
|
100
|
+
unavailable(cause, started);
|
|
101
|
+
return worker.terminate();
|
|
102
|
+
};
|
|
103
|
+
worker.on("message", (reply) => {
|
|
104
|
+
if (!Value.Check(replySchema, reply)) {
|
|
105
|
+
this.stop(new Error("Malformed SQLite worker reply"), true);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if ("ready" in reply) {
|
|
109
|
+
clearTimeout(timeout);
|
|
110
|
+
started = true;
|
|
111
|
+
announce(true);
|
|
112
|
+
if (this.pending.size === 0)
|
|
113
|
+
worker.unref();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const request = this.pending.get(reply.id);
|
|
117
|
+
if (request === undefined)
|
|
118
|
+
return;
|
|
119
|
+
this.pending.delete(reply.id);
|
|
120
|
+
if (this.pending.size === 0)
|
|
121
|
+
worker.unref();
|
|
122
|
+
if ("error" in reply) {
|
|
123
|
+
request.reject(Object.assign(new Error(reply.error), reply));
|
|
124
|
+
} else {
|
|
125
|
+
dev("sqlite", "query", {
|
|
126
|
+
connection: role,
|
|
127
|
+
durationMs: performance.now() - request.at,
|
|
128
|
+
executionMs: reply.executionMs
|
|
129
|
+
});
|
|
130
|
+
request.resolve(reply.rows);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
worker.on("error", (cause) => {
|
|
134
|
+
this.stop(cause instanceof Error ? cause : new Error(String(cause)), true);
|
|
135
|
+
});
|
|
136
|
+
worker.on("exit", (code) => {
|
|
137
|
+
this.stop(new Error(`SQLite ${role} worker exited with code ${code}`), true);
|
|
138
|
+
});
|
|
139
|
+
if (role === "checkpoint")
|
|
140
|
+
worker.unref();
|
|
141
|
+
}
|
|
142
|
+
async query(sql, params) {
|
|
143
|
+
if (!await this.ready)
|
|
144
|
+
return;
|
|
145
|
+
const worker = this.worker;
|
|
146
|
+
if (worker === null)
|
|
147
|
+
throw new Error("SQLite worker stopped");
|
|
148
|
+
const id = this.nextId++;
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
this.pending.set(id, { resolve, reject, at: performance.now() });
|
|
151
|
+
worker.ref();
|
|
152
|
+
try {
|
|
153
|
+
worker.postMessage({ id, sql, params });
|
|
154
|
+
} catch (cause) {
|
|
155
|
+
this.pending.delete(id);
|
|
156
|
+
if (this.pending.size === 0)
|
|
157
|
+
worker.unref();
|
|
158
|
+
reject(cause);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async close() {
|
|
163
|
+
await this.stop(new Error("SQLite worker closed"), false);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function sqliteWorkers2(database, path) {
|
|
167
|
+
let reader = null;
|
|
168
|
+
let readerUnavailable = false;
|
|
169
|
+
let closed = false;
|
|
170
|
+
let checking = false;
|
|
171
|
+
let checkAgain = false;
|
|
172
|
+
let checkpoint = null;
|
|
173
|
+
const warn = (role, cause) => {
|
|
174
|
+
process.emitWarning(`SQLite ${role} worker unavailable; using the main connection: ${cause.message}`, {
|
|
175
|
+
code: "NYTE_SQLITE_WORKER_UNAVAILABLE"
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
const handBack = (cause) => {
|
|
179
|
+
const stopped = checkpoint;
|
|
180
|
+
checkpoint = null;
|
|
181
|
+
stopped?.close();
|
|
182
|
+
if (closed)
|
|
183
|
+
return;
|
|
184
|
+
database.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
185
|
+
warn("checkpoint", cause);
|
|
186
|
+
};
|
|
187
|
+
try {
|
|
188
|
+
checkpoint = new SqliteWorker(path, "checkpoint", handBack);
|
|
189
|
+
checkpoint.ready.then((ready) => {
|
|
190
|
+
if (ready && !closed)
|
|
191
|
+
database.exec("PRAGMA wal_autocheckpoint = 10000");
|
|
192
|
+
});
|
|
193
|
+
} catch (cause) {
|
|
194
|
+
warn("checkpoint", cause instanceof Error ? cause : new Error(String(cause)));
|
|
195
|
+
}
|
|
196
|
+
const check = () => {
|
|
197
|
+
if (checkpoint === null || closed)
|
|
198
|
+
return;
|
|
199
|
+
if (checking) {
|
|
200
|
+
checkAgain = true;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
checking = true;
|
|
204
|
+
checkpoint.query("", []).catch((cause) => {
|
|
205
|
+
if (checkpoint !== null)
|
|
206
|
+
handBack(cause instanceof Error ? cause : new Error(String(cause)));
|
|
207
|
+
}).finally(() => {
|
|
208
|
+
checking = false;
|
|
209
|
+
if (checkAgain) {
|
|
210
|
+
checkAgain = false;
|
|
211
|
+
check();
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
return {
|
|
216
|
+
check,
|
|
217
|
+
async read(sql, params) {
|
|
218
|
+
if (closed)
|
|
219
|
+
throw new Error("SQLite store closed");
|
|
220
|
+
if (readerUnavailable)
|
|
221
|
+
return;
|
|
222
|
+
if (reader === null) {
|
|
223
|
+
try {
|
|
224
|
+
reader = new SqliteWorker(path, "reader", (cause, started) => {
|
|
225
|
+
reader = null;
|
|
226
|
+
readerUnavailable = !started;
|
|
227
|
+
warn("reader", cause);
|
|
228
|
+
});
|
|
229
|
+
} catch (cause) {
|
|
230
|
+
readerUnavailable = true;
|
|
231
|
+
warn("reader", cause instanceof Error ? cause : new Error(String(cause)));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return reader.query(sql, params);
|
|
236
|
+
},
|
|
237
|
+
async close() {
|
|
238
|
+
closed = true;
|
|
239
|
+
await Promise.all([reader?.close(), checkpoint?.close()]);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export { sqliteWorkers2 };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createIgnores2,
|
|
3
|
+
watchTree2
|
|
4
|
+
} from "./canvas-preview-mgcx2b2p.js";
|
|
5
|
+
|
|
6
|
+
// src/local/git-watch.ts
|
|
7
|
+
import { isAbsolute, relative, sep } from "node:path";
|
|
8
|
+
var WATCH_DELAY_MS = 250;
|
|
9
|
+
var POLL_MS = 2000;
|
|
10
|
+
var GIT_STATE = new Set([
|
|
11
|
+
"HEAD",
|
|
12
|
+
"index",
|
|
13
|
+
"packed-refs",
|
|
14
|
+
"config",
|
|
15
|
+
"MERGE_HEAD",
|
|
16
|
+
"CHERRY_PICK_HEAD",
|
|
17
|
+
"REVERT_HEAD",
|
|
18
|
+
"rebase-merge",
|
|
19
|
+
"rebase-apply"
|
|
20
|
+
]);
|
|
21
|
+
function createWatcher2(cwd, read, repository, forget) {
|
|
22
|
+
const listeners = new Set;
|
|
23
|
+
let stop = null;
|
|
24
|
+
let checking = false;
|
|
25
|
+
let again = false;
|
|
26
|
+
const check = async () => {
|
|
27
|
+
if (checking) {
|
|
28
|
+
again = true;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
checking = true;
|
|
32
|
+
do {
|
|
33
|
+
again = false;
|
|
34
|
+
const current = await read().catch(() => null);
|
|
35
|
+
if (current !== null)
|
|
36
|
+
for (const listener of listeners)
|
|
37
|
+
listener(current);
|
|
38
|
+
} while (again && listeners.size > 0);
|
|
39
|
+
checking = false;
|
|
40
|
+
};
|
|
41
|
+
const restart = () => {
|
|
42
|
+
forget();
|
|
43
|
+
stop?.();
|
|
44
|
+
stop = start();
|
|
45
|
+
check();
|
|
46
|
+
};
|
|
47
|
+
const start = () => {
|
|
48
|
+
const disposers = [];
|
|
49
|
+
let polling = null;
|
|
50
|
+
let stopped = false;
|
|
51
|
+
const unwatched = () => {
|
|
52
|
+
polling ??= setInterval(() => void check(), POLL_MS);
|
|
53
|
+
};
|
|
54
|
+
const watchGitDir = (dir) => {
|
|
55
|
+
disposers.push(watchTree2(dir, { delay: WATCH_DELAY_MS, poll: null, unwatched }, (paths) => {
|
|
56
|
+
if ([...paths].some(movesStatus))
|
|
57
|
+
check();
|
|
58
|
+
}));
|
|
59
|
+
};
|
|
60
|
+
repository().then((repo) => {
|
|
61
|
+
if (stopped)
|
|
62
|
+
return;
|
|
63
|
+
const insideGitDir = repo === null ? null : pathInside(cwd, repo.gitDir);
|
|
64
|
+
const ignores = repo === null ? null : createIgnores2(repo.root);
|
|
65
|
+
const moved = async (paths) => {
|
|
66
|
+
let found = "none";
|
|
67
|
+
for (const path of paths) {
|
|
68
|
+
if (path === ".git")
|
|
69
|
+
return "repository";
|
|
70
|
+
if (repo === null || ignores === null)
|
|
71
|
+
continue;
|
|
72
|
+
if (insideGitDir !== null && (path === insideGitDir || path.startsWith(`${insideGitDir}/`))) {
|
|
73
|
+
if (movesStatus(path.slice(insideGitDir.length + 1)))
|
|
74
|
+
found = "status";
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (path.endsWith(".gitignore"))
|
|
78
|
+
ignores.forget(`${repo.prefix}${path}`.split("/").slice(0, -1).join("/"));
|
|
79
|
+
if (found === "none" && !await ignores.ignored(`${repo.prefix}${path}`, false))
|
|
80
|
+
found = "status";
|
|
81
|
+
}
|
|
82
|
+
return found;
|
|
83
|
+
};
|
|
84
|
+
disposers.push(watchTree2(cwd, { delay: WATCH_DELAY_MS, poll: null, unwatched }, (paths) => {
|
|
85
|
+
moved(paths).then((outcome) => {
|
|
86
|
+
if (stopped)
|
|
87
|
+
return;
|
|
88
|
+
if (outcome === "repository")
|
|
89
|
+
restart();
|
|
90
|
+
else if (outcome === "status")
|
|
91
|
+
check();
|
|
92
|
+
});
|
|
93
|
+
}));
|
|
94
|
+
if (repo === null)
|
|
95
|
+
return;
|
|
96
|
+
if (insideGitDir === null)
|
|
97
|
+
watchGitDir(repo.gitDir);
|
|
98
|
+
if (repo.commonDir !== repo.gitDir && pathInside(cwd, repo.commonDir) === null)
|
|
99
|
+
watchGitDir(repo.commonDir);
|
|
100
|
+
});
|
|
101
|
+
return () => {
|
|
102
|
+
stopped = true;
|
|
103
|
+
if (polling !== null)
|
|
104
|
+
clearInterval(polling);
|
|
105
|
+
for (const dispose of disposers)
|
|
106
|
+
dispose();
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
subscribe(listener, fail) {
|
|
111
|
+
listeners.add(listener);
|
|
112
|
+
stop ??= start();
|
|
113
|
+
read().then(listener, fail);
|
|
114
|
+
return () => {
|
|
115
|
+
listeners.delete(listener);
|
|
116
|
+
if (listeners.size === 0) {
|
|
117
|
+
stop?.();
|
|
118
|
+
stop = null;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function movesStatus(path) {
|
|
125
|
+
const [top = ""] = path.split("/");
|
|
126
|
+
return path === "" || GIT_STATE.has(top) || path === "refs" || path.startsWith("refs/heads/") || path.startsWith("refs/remotes/");
|
|
127
|
+
}
|
|
128
|
+
function pathInside(cwd, dir) {
|
|
129
|
+
const inside = relative(cwd, dir);
|
|
130
|
+
return inside.startsWith("..") || isAbsolute(inside) ? null : inside.split(sep).join("/");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export { createWatcher2 };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CanvasPreviewer } from "@nyte-ai/plugin/core/canvas-preview";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the shell a previewer serves: every file of the canvas package's
|
|
4
|
+
* `dist/shell`, base64 by its path from it (`index.html`,
|
|
5
|
+
* `libraries/three.js`), as `@nyte-ai/canvas/shell-files` exports them.
|
|
6
|
+
*
|
|
7
|
+
* @category host
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
export type CanvasShellFiles = Readonly<Record<string, string>>;
|
|
11
|
+
/**
|
|
12
|
+
* Finds a Chromium to preview with: `NYTE_CANVAS_CHROMIUM`, then
|
|
13
|
+
* Playwright's headless shell or Chromium, then an installed Chrome or
|
|
14
|
+
* Chromium. Undefined when there is none.
|
|
15
|
+
*
|
|
16
|
+
* @category host
|
|
17
|
+
* @since 0.1.0
|
|
18
|
+
*/
|
|
19
|
+
export declare function findChromium(): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a previewer over a headless Chromium on this machine
|
|
22
|
+
* (`findChromium`), serving `shell`; it answers `unavailable` when there is
|
|
23
|
+
* no Chromium or it fails to start, and stops the browser when the
|
|
24
|
+
* preview's signal aborts.
|
|
25
|
+
*
|
|
26
|
+
* @category host
|
|
27
|
+
* @since 0.1.0
|
|
28
|
+
*/
|
|
29
|
+
export declare function chromiumCanvasPreview(shell: CanvasShellFiles, executable?: () => string | undefined): CanvasPreviewer;
|