@kvman/kernel 0.1.0
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 +11 -0
- package/dist/clock.d.ts +8 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +13 -0
- package/dist/clock.js.map +1 -0
- package/dist/ctx/extension-ctx.d.ts +22 -0
- package/dist/ctx/extension-ctx.d.ts.map +1 -0
- package/dist/ctx/extension-ctx.js +78 -0
- package/dist/ctx/extension-ctx.js.map +1 -0
- package/dist/ctx/files-calls.d.ts +5 -0
- package/dist/ctx/files-calls.d.ts.map +1 -0
- package/dist/ctx/files-calls.js +26 -0
- package/dist/ctx/files-calls.js.map +1 -0
- package/dist/ctx/job-calls.d.ts +12 -0
- package/dist/ctx/job-calls.d.ts.map +1 -0
- package/dist/ctx/job-calls.js +73 -0
- package/dist/ctx/job-calls.js.map +1 -0
- package/dist/ctx/processes-calls.d.ts +11 -0
- package/dist/ctx/processes-calls.d.ts.map +1 -0
- package/dist/ctx/processes-calls.js +50 -0
- package/dist/ctx/processes-calls.js.map +1 -0
- package/dist/ctx/settings-calls.d.ts +5 -0
- package/dist/ctx/settings-calls.d.ts.map +1 -0
- package/dist/ctx/settings-calls.js +30 -0
- package/dist/ctx/settings-calls.js.map +1 -0
- package/dist/extensions/load-order.d.ts +13 -0
- package/dist/extensions/load-order.d.ts.map +1 -0
- package/dist/extensions/load-order.js +111 -0
- package/dist/extensions/load-order.js.map +1 -0
- package/dist/extensions/manifests.d.ts +16 -0
- package/dist/extensions/manifests.d.ts.map +1 -0
- package/dist/extensions/manifests.js +50 -0
- package/dist/extensions/manifests.js.map +1 -0
- package/dist/extensions/npm-install.d.ts +9 -0
- package/dist/extensions/npm-install.d.ts.map +1 -0
- package/dist/extensions/npm-install.js +39 -0
- package/dist/extensions/npm-install.js.map +1 -0
- package/dist/extensions/trust.d.ts +11 -0
- package/dist/extensions/trust.d.ts.map +1 -0
- package/dist/extensions/trust.js +27 -0
- package/dist/extensions/trust.js.map +1 -0
- package/dist/files/file-access.d.ts +6 -0
- package/dist/files/file-access.d.ts.map +1 -0
- package/dist/files/file-access.js +21 -0
- package/dist/files/file-access.js.map +1 -0
- package/dist/files/files.d.ts +31 -0
- package/dist/files/files.d.ts.map +1 -0
- package/dist/files/files.js +73 -0
- package/dist/files/files.js.map +1 -0
- package/dist/http/call-routes.d.ts +4 -0
- package/dist/http/call-routes.d.ts.map +1 -0
- package/dist/http/call-routes.js +72 -0
- package/dist/http/call-routes.js.map +1 -0
- package/dist/http/envelope.d.ts +8 -0
- package/dist/http/envelope.d.ts.map +1 -0
- package/dist/http/envelope.js +17 -0
- package/dist/http/envelope.js.map +1 -0
- package/dist/http/file-routes.d.ts +5 -0
- package/dist/http/file-routes.d.ts.map +1 -0
- package/dist/http/file-routes.js +47 -0
- package/dist/http/file-routes.js.map +1 -0
- package/dist/http/http-app.d.ts +11 -0
- package/dist/http/http-app.d.ts.map +1 -0
- package/dist/http/http-app.js +31 -0
- package/dist/http/http-app.js.map +1 -0
- package/dist/http/http-server.d.ts +9 -0
- package/dist/http/http-server.d.ts.map +1 -0
- package/dist/http/http-server.js +38 -0
- package/dist/http/http-server.js.map +1 -0
- package/dist/http/job-events.d.ts +18 -0
- package/dist/http/job-events.d.ts.map +1 -0
- package/dist/http/job-events.js +48 -0
- package/dist/http/job-events.js.map +1 -0
- package/dist/http/job-routes.d.ts +4 -0
- package/dist/http/job-routes.d.ts.map +1 -0
- package/dist/http/job-routes.js +20 -0
- package/dist/http/job-routes.js.map +1 -0
- package/dist/http/own-origin.d.ts +2 -0
- package/dist/http/own-origin.d.ts.map +1 -0
- package/dist/http/own-origin.js +9 -0
- package/dist/http/own-origin.js.map +1 -0
- package/dist/http/request-body.d.ts +19 -0
- package/dist/http/request-body.d.ts.map +1 -0
- package/dist/http/request-body.js +72 -0
- package/dist/http/request-body.js.map +1 -0
- package/dist/http/static-files.d.ts +3 -0
- package/dist/http/static-files.d.ts.map +1 -0
- package/dist/http/static-files.js +35 -0
- package/dist/http/static-files.js.map +1 -0
- package/dist/http/web-routes.d.ts +4 -0
- package/dist/http/web-routes.d.ts.map +1 -0
- package/dist/http/web-routes.js +23 -0
- package/dist/http/web-routes.js.map +1 -0
- package/dist/ids.d.ts +6 -0
- package/dist/ids.d.ts.map +1 -0
- package/dist/ids.js +42 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/current-job.d.ts +19 -0
- package/dist/jobs/current-job.d.ts.map +1 -0
- package/dist/jobs/current-job.js +20 -0
- package/dist/jobs/current-job.js.map +1 -0
- package/dist/jobs/dispatcher.d.ts +40 -0
- package/dist/jobs/dispatcher.d.ts.map +1 -0
- package/dist/jobs/dispatcher.js +201 -0
- package/dist/jobs/dispatcher.js.map +1 -0
- package/dist/jobs/handlers.d.ts +19 -0
- package/dist/jobs/handlers.d.ts.map +1 -0
- package/dist/jobs/handlers.js +54 -0
- package/dist/jobs/handlers.js.map +1 -0
- package/dist/jobs/job-rows.d.ts +63 -0
- package/dist/jobs/job-rows.d.ts.map +1 -0
- package/dist/jobs/job-rows.js +111 -0
- package/dist/jobs/job-rows.js.map +1 -0
- package/dist/jobs/progress-hub.d.ts +12 -0
- package/dist/jobs/progress-hub.d.ts.map +1 -0
- package/dist/jobs/progress-hub.js +40 -0
- package/dist/jobs/progress-hub.js.map +1 -0
- package/dist/jobs/registry.d.ts +38 -0
- package/dist/jobs/registry.d.ts.map +1 -0
- package/dist/jobs/registry.js +89 -0
- package/dist/jobs/registry.js.map +1 -0
- package/dist/jobs/retry-policy.d.ts +4 -0
- package/dist/jobs/retry-policy.d.ts.map +1 -0
- package/dist/jobs/retry-policy.js +10 -0
- package/dist/jobs/retry-policy.js.map +1 -0
- package/dist/jobs/run-job.d.ts +26 -0
- package/dist/jobs/run-job.d.ts.map +1 -0
- package/dist/jobs/run-job.js +120 -0
- package/dist/jobs/run-job.js.map +1 -0
- package/dist/kernel-api/extensions-api.d.ts +4 -0
- package/dist/kernel-api/extensions-api.d.ts.map +1 -0
- package/dist/kernel-api/extensions-api.js +32 -0
- package/dist/kernel-api/extensions-api.js.map +1 -0
- package/dist/kernel-api/folder-api.d.ts +4 -0
- package/dist/kernel-api/folder-api.d.ts.map +1 -0
- package/dist/kernel-api/folder-api.js +54 -0
- package/dist/kernel-api/folder-api.js.map +1 -0
- package/dist/kernel-api/folder-name.d.ts +3 -0
- package/dist/kernel-api/folder-name.d.ts.map +1 -0
- package/dist/kernel-api/folder-name.js +26 -0
- package/dist/kernel-api/folder-name.js.map +1 -0
- package/dist/kernel-api/health-api.d.ts +4 -0
- package/dist/kernel-api/health-api.d.ts.map +1 -0
- package/dist/kernel-api/health-api.js +8 -0
- package/dist/kernel-api/health-api.js.map +1 -0
- package/dist/kernel-api/jobs-files-api.d.ts +4 -0
- package/dist/kernel-api/jobs-files-api.d.ts.map +1 -0
- package/dist/kernel-api/jobs-files-api.js +18 -0
- package/dist/kernel-api/jobs-files-api.js.map +1 -0
- package/dist/kernel-api/json-schemas.d.ts +3 -0
- package/dist/kernel-api/json-schemas.d.ts.map +1 -0
- package/dist/kernel-api/json-schemas.js +16 -0
- package/dist/kernel-api/json-schemas.js.map +1 -0
- package/dist/kernel-api/kernel-api-services.d.ts +17 -0
- package/dist/kernel-api/kernel-api-services.d.ts.map +1 -0
- package/dist/kernel-api/kernel-api-services.js +2 -0
- package/dist/kernel-api/kernel-api-services.js.map +1 -0
- package/dist/kernel-api/kernel-registrations.d.ts +19 -0
- package/dist/kernel-api/kernel-registrations.d.ts.map +1 -0
- package/dist/kernel-api/kernel-registrations.js +14 -0
- package/dist/kernel-api/kernel-registrations.js.map +1 -0
- package/dist/kernel-api/preset-api.d.ts +4 -0
- package/dist/kernel-api/preset-api.d.ts.map +1 -0
- package/dist/kernel-api/preset-api.js +10 -0
- package/dist/kernel-api/preset-api.js.map +1 -0
- package/dist/kernel-api/register-kernel-api.d.ts +4 -0
- package/dist/kernel-api/register-kernel-api.d.ts.map +1 -0
- package/dist/kernel-api/register-kernel-api.js +24 -0
- package/dist/kernel-api/register-kernel-api.js.map +1 -0
- package/dist/kernel-api/restart-api.d.ts +4 -0
- package/dist/kernel-api/restart-api.d.ts.map +1 -0
- package/dist/kernel-api/restart-api.js +10 -0
- package/dist/kernel-api/restart-api.js.map +1 -0
- package/dist/kernel-api/secrets-api.d.ts +4 -0
- package/dist/kernel-api/secrets-api.d.ts.map +1 -0
- package/dist/kernel-api/secrets-api.js +23 -0
- package/dist/kernel-api/secrets-api.js.map +1 -0
- package/dist/kernel-api/settings-api.d.ts +4 -0
- package/dist/kernel-api/settings-api.d.ts.map +1 -0
- package/dist/kernel-api/settings-api.js +33 -0
- package/dist/kernel-api/settings-api.js.map +1 -0
- package/dist/kernel-api/workspace-api.d.ts +4 -0
- package/dist/kernel-api/workspace-api.d.ts.map +1 -0
- package/dist/kernel-api/workspace-api.js +13 -0
- package/dist/kernel-api/workspace-api.js.map +1 -0
- package/dist/kernel-lifecycle.d.ts +8 -0
- package/dist/kernel-lifecycle.d.ts.map +1 -0
- package/dist/kernel-lifecycle.js +56 -0
- package/dist/kernel-lifecycle.js.map +1 -0
- package/dist/kernel-requests.d.ts +25 -0
- package/dist/kernel-requests.d.ts.map +1 -0
- package/dist/kernel-requests.js +63 -0
- package/dist/kernel-requests.js.map +1 -0
- package/dist/kernel-version.d.ts +2 -0
- package/dist/kernel-version.d.ts.map +1 -0
- package/dist/kernel-version.js +8 -0
- package/dist/kernel-version.js.map +1 -0
- package/dist/kernel-web.d.ts +36 -0
- package/dist/kernel-web.d.ts.map +1 -0
- package/dist/kernel-web.js +26 -0
- package/dist/kernel-web.js.map +1 -0
- package/dist/kernel.d.ts +44 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +157 -0
- package/dist/kernel.js.map +1 -0
- package/dist/limits.d.ts +6 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +8 -0
- package/dist/limits.js.map +1 -0
- package/dist/localization/catalogs.d.ts +15 -0
- package/dist/localization/catalogs.d.ts.map +1 -0
- package/dist/localization/catalogs.js +66 -0
- package/dist/localization/catalogs.js.map +1 -0
- package/dist/logging/log-file.d.ts +7 -0
- package/dist/logging/log-file.d.ts.map +1 -0
- package/dist/logging/log-file.js +12 -0
- package/dist/logging/log-file.js.map +1 -0
- package/dist/logging/logger.d.ts +12 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +14 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/terminal-lines.d.ts +4 -0
- package/dist/logging/terminal-lines.d.ts.map +1 -0
- package/dist/logging/terminal-lines.js +16 -0
- package/dist/logging/terminal-lines.js.map +1 -0
- package/dist/preset-edit/install-source.d.ts +8 -0
- package/dist/preset-edit/install-source.d.ts.map +1 -0
- package/dist/preset-edit/install-source.js +36 -0
- package/dist/preset-edit/install-source.js.map +1 -0
- package/dist/preset-edit/preset-backup.d.ts +10 -0
- package/dist/preset-edit/preset-backup.d.ts.map +1 -0
- package/dist/preset-edit/preset-backup.js +45 -0
- package/dist/preset-edit/preset-backup.js.map +1 -0
- package/dist/preset-edit/preset-files.d.ts +6 -0
- package/dist/preset-edit/preset-files.d.ts.map +1 -0
- package/dist/preset-edit/preset-files.js +56 -0
- package/dist/preset-edit/preset-files.js.map +1 -0
- package/dist/preset-edit/preset-source.d.ts +7 -0
- package/dist/preset-edit/preset-source.d.ts.map +1 -0
- package/dist/preset-edit/preset-source.js +2 -0
- package/dist/preset-edit/preset-source.js.map +1 -0
- package/dist/preset-edit/preset-store.d.ts +22 -0
- package/dist/preset-edit/preset-store.d.ts.map +1 -0
- package/dist/preset-edit/preset-store.js +70 -0
- package/dist/preset-edit/preset-store.js.map +1 -0
- package/dist/problems.d.ts +3 -0
- package/dist/problems.d.ts.map +1 -0
- package/dist/problems.js +6 -0
- package/dist/problems.js.map +1 -0
- package/dist/processes/process-kill.d.ts +16 -0
- package/dist/processes/process-kill.d.ts.map +1 -0
- package/dist/processes/process-kill.js +45 -0
- package/dist/processes/process-kill.js.map +1 -0
- package/dist/processes/process-log.d.ts +10 -0
- package/dist/processes/process-log.d.ts.map +1 -0
- package/dist/processes/process-log.js +41 -0
- package/dist/processes/process-log.js.map +1 -0
- package/dist/processes/process-rows.d.ts +11 -0
- package/dist/processes/process-rows.d.ts.map +1 -0
- package/dist/processes/process-rows.js +21 -0
- package/dist/processes/process-rows.js.map +1 -0
- package/dist/processes/process-service.d.ts +30 -0
- package/dist/processes/process-service.d.ts.map +1 -0
- package/dist/processes/process-service.js +110 -0
- package/dist/processes/process-service.js.map +1 -0
- package/dist/reload/reload-extensions.d.ts +5 -0
- package/dist/reload/reload-extensions.d.ts.map +1 -0
- package/dist/reload/reload-extensions.js +25 -0
- package/dist/reload/reload-extensions.js.map +1 -0
- package/dist/reload/watcher.d.ts +7 -0
- package/dist/reload/watcher.d.ts.map +1 -0
- package/dist/reload/watcher.js +40 -0
- package/dist/reload/watcher.js.map +1 -0
- package/dist/run/extension-run.d.ts +36 -0
- package/dist/run/extension-run.d.ts.map +1 -0
- package/dist/run/extension-run.js +81 -0
- package/dist/run/extension-run.js.map +1 -0
- package/dist/schedules/schedule-rows.d.ts +27 -0
- package/dist/schedules/schedule-rows.d.ts.map +1 -0
- package/dist/schedules/schedule-rows.js +70 -0
- package/dist/schedules/schedule-rows.js.map +1 -0
- package/dist/sdk-version.d.ts +2 -0
- package/dist/sdk-version.d.ts.map +1 -0
- package/dist/sdk-version.js +10 -0
- package/dist/sdk-version.js.map +1 -0
- package/dist/secrets/secrets-file.d.ts +11 -0
- package/dist/secrets/secrets-file.d.ts.map +1 -0
- package/dist/secrets/secrets-file.js +50 -0
- package/dist/secrets/secrets-file.js.map +1 -0
- package/dist/settings/kernel-settings.d.ts +4 -0
- package/dist/settings/kernel-settings.d.ts.map +1 -0
- package/dist/settings/kernel-settings.js +20 -0
- package/dist/settings/kernel-settings.js.map +1 -0
- package/dist/settings/preset-check.d.ts +4 -0
- package/dist/settings/preset-check.d.ts.map +1 -0
- package/dist/settings/preset-check.js +19 -0
- package/dist/settings/preset-check.js.map +1 -0
- package/dist/settings/settings.d.ts +31 -0
- package/dist/settings/settings.d.ts.map +1 -0
- package/dist/settings/settings.js +68 -0
- package/dist/settings/settings.js.map +1 -0
- package/dist/storage/database.d.ts +6 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +31 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/schema.d.ts +2 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +108 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/store/collections.d.ts +6 -0
- package/dist/store/collections.d.ts.map +1 -0
- package/dist/store/collections.js +63 -0
- package/dist/store/collections.js.map +1 -0
- package/dist/store/filters.d.ts +10 -0
- package/dist/store/filters.d.ts.map +1 -0
- package/dist/store/filters.js +40 -0
- package/dist/store/filters.js.map +1 -0
- package/dist/store/json-values.d.ts +6 -0
- package/dist/store/json-values.d.ts.map +1 -0
- package/dist/store/json-values.js +20 -0
- package/dist/store/json-values.js.map +1 -0
- package/dist/store/kv.d.ts +9 -0
- package/dist/store/kv.d.ts.map +1 -0
- package/dist/store/kv.js +23 -0
- package/dist/store/kv.js.map +1 -0
- package/dist/store/store.d.ts +11 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +62 -0
- package/dist/store/store.js.map +1 -0
- package/dist/wasm-code-gc.d.ts +2 -0
- package/dist/wasm-code-gc.d.ts.map +1 -0
- package/dist/wasm-code-gc.js +9 -0
- package/dist/wasm-code-gc.js.map +1 -0
- package/dist/workers/pool.d.ts +31 -0
- package/dist/workers/pool.d.ts.map +1 -0
- package/dist/workers/pool.js +208 -0
- package/dist/workers/pool.js.map +1 -0
- package/dist/workers/protocol.d.ts +431 -0
- package/dist/workers/protocol.d.ts.map +1 -0
- package/dist/workers/protocol.js +93 -0
- package/dist/workers/protocol.js.map +1 -0
- package/dist/workers/root-runner.d.ts +15 -0
- package/dist/workers/root-runner.d.ts.map +1 -0
- package/dist/workers/root-runner.js +63 -0
- package/dist/workers/root-runner.js.map +1 -0
- package/dist/workers/sdk-resolution.d.ts +2 -0
- package/dist/workers/sdk-resolution.d.ts.map +1 -0
- package/dist/workers/sdk-resolution.js +14 -0
- package/dist/workers/sdk-resolution.js.map +1 -0
- package/dist/workers/worker-main.d.ts +2 -0
- package/dist/workers/worker-main.d.ts.map +1 -0
- package/dist/workers/worker-main.js +123 -0
- package/dist/workers/worker-main.js.map +1 -0
- package/dist/workspaces/workspaces.d.ts +17 -0
- package/dist/workspaces/workspaces.d.ts.map +1 -0
- package/dist/workspaces/workspaces.js +85 -0
- package/dist/workspaces/workspaces.js.map +1 -0
- package/locales/ar.json +70 -0
- package/locales/en.json +70 -0
- package/package.json +45 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from '@kvman/sdk';
|
|
2
|
+
import { kernelProblem } from "../problems.js";
|
|
3
|
+
// What the extensions registered in one worker, checked as they register (plan 02 §2.9, §2.13, 03 §3.1).
|
|
4
|
+
const mebibyte = 1024 * 1024;
|
|
5
|
+
const defaultBytes = mebibyte;
|
|
6
|
+
const maximumBytes = 32 * mebibyte;
|
|
7
|
+
const defaultTimeoutMs = 600_000;
|
|
8
|
+
const defaultRetries = 3;
|
|
9
|
+
const namePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*(?:\.[a-z][a-z0-9]*(?:-[a-z0-9]+)*)+$/;
|
|
10
|
+
// A setting key's segments are lower camelCase, such as `kvai.defaultModel` (ADR 0009, 64).
|
|
11
|
+
const settingKeyPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*(?:\.[a-z][a-zA-Z0-9]*)+$/;
|
|
12
|
+
const optionsSchema = z.object({
|
|
13
|
+
description: z.string().trim().min(1),
|
|
14
|
+
input: z.instanceof(z.ZodType),
|
|
15
|
+
output: z.instanceof(z.ZodType),
|
|
16
|
+
handle: z.custom((value) => typeof value === 'function', 'handle must be a function'),
|
|
17
|
+
public: z.boolean().optional(),
|
|
18
|
+
timeoutMs: z.number().int().positive().optional(),
|
|
19
|
+
retries: z.number().int().nonnegative().optional(),
|
|
20
|
+
syncOnly: z.boolean().optional(),
|
|
21
|
+
maxInputBytes: z.number().int().positive().max(maximumBytes).optional(),
|
|
22
|
+
maxOutputBytes: z.number().int().positive().max(maximumBytes).optional(),
|
|
23
|
+
});
|
|
24
|
+
const settingSchema = z.object({
|
|
25
|
+
description: z.string().trim().min(1),
|
|
26
|
+
schema: z.instanceof(z.ZodType),
|
|
27
|
+
scopes: z.union([z.tuple([z.literal('global'), z.literal('workspace')]), z.tuple([z.literal('global')]), z.tuple([])]).optional(),
|
|
28
|
+
});
|
|
29
|
+
function invalid(owner, message, name) {
|
|
30
|
+
return kernelProblem('EXTENSION_INVALID', `${owner.name}: ${message}`, { extension: owner.name, name });
|
|
31
|
+
}
|
|
32
|
+
export function createRegistry() {
|
|
33
|
+
return { jobs: new Map(), settings: new Map(), handlers: [], sealed: false };
|
|
34
|
+
}
|
|
35
|
+
const jobNameRule = { pattern: namePattern, segments: 'in lowercase kebab case' };
|
|
36
|
+
const settingKeyRule = { pattern: settingKeyPattern, segments: 'with lower camelCase segments' };
|
|
37
|
+
function checkName(registry, owner, name, taken, rule = jobNameRule) {
|
|
38
|
+
if (registry.sealed)
|
|
39
|
+
throw invalid(owner, `"${name}" was registered after the entry returned; registrations are sealed.`, name);
|
|
40
|
+
if (!rule.pattern.test(name) || !name.startsWith(`${owner.namespace}.`)) {
|
|
41
|
+
throw invalid(owner, `"${name}" must be <namespace>.<segment>… ${rule.segments}, starting with "${owner.namespace}.".`, name);
|
|
42
|
+
}
|
|
43
|
+
if (taken)
|
|
44
|
+
throw invalid(owner, `"${name}" is registered twice.`, name);
|
|
45
|
+
}
|
|
46
|
+
export function registerJob(registry, owner, kind, name, options) {
|
|
47
|
+
checkName(registry, owner, name, registry.jobs.has(name));
|
|
48
|
+
const parsed = optionsSchema.safeParse(options);
|
|
49
|
+
if (!parsed.success)
|
|
50
|
+
throw invalid(owner, `the registration of "${name}" is invalid (${z.prettifyError(parsed.error)}).`, name);
|
|
51
|
+
const retries = 'retries' in options ? options.retries : undefined;
|
|
52
|
+
const syncOnly = 'syncOnly' in options ? options.syncOnly : undefined;
|
|
53
|
+
registry.jobs.set(name, {
|
|
54
|
+
kind,
|
|
55
|
+
name,
|
|
56
|
+
owner: owner.name,
|
|
57
|
+
description: parsed.data.description,
|
|
58
|
+
input: options.input,
|
|
59
|
+
output: options.output,
|
|
60
|
+
start: (input) => {
|
|
61
|
+
const parsed = options.input.safeParse(input);
|
|
62
|
+
return parsed.success ? { run: () => options.handle(parsed.data) } : { error: parsed.error };
|
|
63
|
+
},
|
|
64
|
+
public: options.public ?? false,
|
|
65
|
+
timeoutMs: options.timeoutMs ?? defaultTimeoutMs,
|
|
66
|
+
retries: kind === 'command' ? (retries ?? defaultRetries) : 0,
|
|
67
|
+
maxInputBytes: options.maxInputBytes ?? defaultBytes,
|
|
68
|
+
maxOutputBytes: options.maxOutputBytes ?? defaultBytes,
|
|
69
|
+
syncOnly: kind === 'command' && syncOnly === true,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export function registerSetting(registry, owner, key, options) {
|
|
73
|
+
checkName(registry, owner, key, registry.settings.has(key), settingKeyRule);
|
|
74
|
+
const parsed = settingSchema.safeParse(options);
|
|
75
|
+
if (!parsed.success)
|
|
76
|
+
throw invalid(owner, `the setting "${key}" is invalid (${z.prettifyError(parsed.error)}).`, key);
|
|
77
|
+
if (Object.hasOwn(options, 'default') && !options.schema.safeParse(options.default).success) {
|
|
78
|
+
throw invalid(owner, `the default of the setting "${key}" doesn't fit its schema.`, key);
|
|
79
|
+
}
|
|
80
|
+
registry.settings.set(key, {
|
|
81
|
+
key,
|
|
82
|
+
extension: owner.name,
|
|
83
|
+
description: parsed.data.description,
|
|
84
|
+
schema: options.schema,
|
|
85
|
+
defaultValue: Object.hasOwn(options, 'default') ? { value: options.default } : undefined,
|
|
86
|
+
scopes: options.scopes ?? ['global', 'workspace'],
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/jobs/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../src/jobs/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAM1C,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEnD;AAGD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Which failed attempts run again, and when (plan 02 §2.3, ADR 0009, 14).
|
|
2
|
+
const retriedCodes = new Set(['HANDLER_FAILED', 'TIMEOUT', 'WORKER_CRASHED', 'INTERRUPTED']);
|
|
3
|
+
export function isRetried(problem) {
|
|
4
|
+
return retriedCodes.has(problem.code);
|
|
5
|
+
}
|
|
6
|
+
// 1 s after the first attempt, then 2 s, 4 s, …
|
|
7
|
+
export function backoffMs(attempts) {
|
|
8
|
+
return 1000 * 2 ** (attempts - 1);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=retry-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.js","sourceRoot":"","sources":["../../src/jobs/retry-policy.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAE1E,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC,CAAC;AAElH,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Caller, type Problem, type Workspace } from '@kvman/sdk';
|
|
2
|
+
import type { KernelLogger } from '../logging/logger.ts';
|
|
3
|
+
import type { SyncEnd } from '../workers/protocol.ts';
|
|
4
|
+
import { type RunningJob } from './current-job.ts';
|
|
5
|
+
import type { Registry } from './registry.ts';
|
|
6
|
+
export declare const maximumDepth = 16;
|
|
7
|
+
export type JobEnvironment = {
|
|
8
|
+
registry: Registry;
|
|
9
|
+
logger: KernelLogger;
|
|
10
|
+
reportSyncEnd: (end: SyncEnd) => void;
|
|
11
|
+
};
|
|
12
|
+
export type JobRequest = {
|
|
13
|
+
id: string;
|
|
14
|
+
rootId: string;
|
|
15
|
+
name: string;
|
|
16
|
+
input: unknown;
|
|
17
|
+
workspace: Workspace;
|
|
18
|
+
caller: Caller;
|
|
19
|
+
parent: RunningJob | undefined;
|
|
20
|
+
signal: AbortSignal;
|
|
21
|
+
fromHandler: boolean;
|
|
22
|
+
handlerExtension: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
export declare function syncEndOf(request: JobRequest, problem: Problem, reason: string): SyncEnd;
|
|
25
|
+
export declare function runJob(environment: JobEnvironment, request: JobRequest): Promise<unknown>;
|
|
26
|
+
//# sourceMappingURL=run-job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-job.d.ts","sourceRoot":"","sources":["../../src/jobs/run-job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,YAAY,CAAC;AAC7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,KAAK,EAAgB,QAAQ,EAAc,MAAM,eAAe,CAAC;AAKxE,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,CAAC;AAEjH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC,CAAC;AAoGF,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKxF;AAID,wBAAsB,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ/F"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { ProblemError } from '@kvman/sdk';
|
|
2
|
+
import { kernelProblem } from "../problems.js";
|
|
3
|
+
import { runInJob } from "./current-job.js";
|
|
4
|
+
// Runs one job on this worker (plan 02 §2.1–§2.3, §2.13, §2.15): access, depth, size caps, input and output
|
|
5
|
+
// validation, the timeout, and turning any failure into a Problem.
|
|
6
|
+
export const maximumDepth = 16;
|
|
7
|
+
function jsonBytes(value) {
|
|
8
|
+
return Buffer.byteLength(JSON.stringify(value) ?? '');
|
|
9
|
+
}
|
|
10
|
+
function runnableOf(registry, request) {
|
|
11
|
+
if (request.handlerExtension !== undefined) {
|
|
12
|
+
const handler = registry.handlers.find((entry) => entry.point === request.name && entry.owner === request.handlerExtension);
|
|
13
|
+
if (handler === undefined)
|
|
14
|
+
throw kernelProblem('NOT_FOUND', `${request.handlerExtension} has no handler for ${request.name}.`, { name: request.name });
|
|
15
|
+
return { kind: 'command', name: handler.point, owner: handler.owner, timeoutMs: handler.timeoutMs, start: handler.start, registration: undefined };
|
|
16
|
+
}
|
|
17
|
+
const registration = registry.jobs.get(request.name);
|
|
18
|
+
if (registration === undefined)
|
|
19
|
+
throw kernelProblem('NOT_FOUND', `There is no command or query ${request.name}.`, { name: request.name });
|
|
20
|
+
return { ...registration, registration };
|
|
21
|
+
}
|
|
22
|
+
function checkAccess(registration, request) {
|
|
23
|
+
const caller = request.caller;
|
|
24
|
+
const own = caller.kind === 'extension' && caller.name === registration.owner;
|
|
25
|
+
if (!registration.public && caller.kind !== 'kernel' && !own) {
|
|
26
|
+
throw kernelProblem('NOT_PUBLIC', `${registration.name} is private to ${registration.owner}.`, { name: registration.name });
|
|
27
|
+
}
|
|
28
|
+
if (request.parent?.kind === 'query' && registration.kind === 'command') {
|
|
29
|
+
throw kernelProblem('READ_ONLY', `The query ${request.parent.name} can't run the command ${registration.name}.`, { name: registration.name });
|
|
30
|
+
}
|
|
31
|
+
if ((request.parent?.depth ?? 0) + 1 > maximumDepth) {
|
|
32
|
+
throw kernelProblem('TOO_DEEP', `Sync calls are nested deeper than ${maximumDepth}.`, { limit: maximumDepth });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function checkSize(registration, value, part) {
|
|
36
|
+
const limit = part === 'input' ? registration.maxInputBytes : registration.maxOutputBytes;
|
|
37
|
+
if (jsonBytes(value) > limit)
|
|
38
|
+
throw kernelProblem('TOO_LARGE', `The ${part} of ${registration.name} is over ${limit} bytes of JSON.`, { limit });
|
|
39
|
+
}
|
|
40
|
+
function invalid(name, part, error) {
|
|
41
|
+
const issues = error.issues.map((issue) => ({ path: issue.path.map(String).join('.'), message: issue.message }));
|
|
42
|
+
return kernelProblem('VALIDATION_FAILED', `The ${part} of ${name} is invalid.`, { issues });
|
|
43
|
+
}
|
|
44
|
+
function checkedOutput(registration, output) {
|
|
45
|
+
if (registration === undefined)
|
|
46
|
+
return null;
|
|
47
|
+
checkSize(registration, output, 'output');
|
|
48
|
+
const parsed = registration.output.safeParse(output);
|
|
49
|
+
if (!parsed.success)
|
|
50
|
+
throw invalid(registration.name, 'output', parsed.error);
|
|
51
|
+
return parsed.data;
|
|
52
|
+
}
|
|
53
|
+
async function withTimeout(runnable, controller, run) {
|
|
54
|
+
let timer;
|
|
55
|
+
const timedOut = new Promise((_resolve, reject) => {
|
|
56
|
+
timer = setTimeout(() => {
|
|
57
|
+
const problem = kernelProblem('TIMEOUT', `${runnable.name} ran past ${runnable.timeoutMs} ms.`, { limit: runnable.timeoutMs });
|
|
58
|
+
controller.abort(problem);
|
|
59
|
+
reject(problem);
|
|
60
|
+
}, runnable.timeoutMs);
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
return await Promise.race([run(), timedOut]);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function problemOf(error, name, logger, jobId) {
|
|
70
|
+
if (error instanceof ProblemError)
|
|
71
|
+
return error.problem;
|
|
72
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
73
|
+
logger.error('A handler failed with an error that is not a Problem.', { name, jobId, error: failure.message, stack: failure.stack ?? '' });
|
|
74
|
+
return { code: 'HANDLER_FAILED', message: `The handler of ${name} failed.` };
|
|
75
|
+
}
|
|
76
|
+
async function runChecked(registry, request) {
|
|
77
|
+
const runnable = runnableOf(registry, request);
|
|
78
|
+
if (runnable.registration !== undefined) {
|
|
79
|
+
checkAccess(runnable.registration, request);
|
|
80
|
+
checkSize(runnable.registration, request.input, 'input');
|
|
81
|
+
}
|
|
82
|
+
const started = runnable.start(request.input);
|
|
83
|
+
if ('error' in started)
|
|
84
|
+
throw invalid(runnable.name, 'input', started.error);
|
|
85
|
+
const controller = new AbortController();
|
|
86
|
+
const job = {
|
|
87
|
+
id: request.id,
|
|
88
|
+
rootId: request.rootId,
|
|
89
|
+
name: runnable.name,
|
|
90
|
+
kind: runnable.kind,
|
|
91
|
+
owner: runnable.owner,
|
|
92
|
+
workspace: request.workspace,
|
|
93
|
+
caller: request.caller,
|
|
94
|
+
signal: AbortSignal.any([request.signal, controller.signal]),
|
|
95
|
+
depth: (request.parent?.depth ?? 0) + 1,
|
|
96
|
+
fromHandler: request.fromHandler,
|
|
97
|
+
};
|
|
98
|
+
const output = await withTimeout(runnable, controller, () => runInJob(job, async () => started.run()));
|
|
99
|
+
return checkedOutput(runnable.registration, output);
|
|
100
|
+
}
|
|
101
|
+
export function syncEndOf(request, problem, reason) {
|
|
102
|
+
const base = { jobId: request.id, rootId: request.rootId, name: request.name, caller: request.caller, workspaceId: request.workspace.id };
|
|
103
|
+
return problem.code === 'CANCELLED'
|
|
104
|
+
? { point: 'kernel.job.cancelled', input: { ...base, reason }, workspaceId: request.workspace.id }
|
|
105
|
+
: { point: 'kernel.job.failed', input: { ...base, problem, attempts: 1 }, workspaceId: request.workspace.id };
|
|
106
|
+
}
|
|
107
|
+
// Any failure leaves as a ProblemError, so a nested caller and the worker see only Problems. A nested sync job that
|
|
108
|
+
// fails is reported for the kernel's handler points here; the root job's end is reported by whoever runs the root.
|
|
109
|
+
export async function runJob(environment, request) {
|
|
110
|
+
try {
|
|
111
|
+
return await runChecked(environment.registry, request);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const problem = problemOf(error, request.name, environment.logger, request.id);
|
|
115
|
+
if (request.parent !== undefined && !request.fromHandler)
|
|
116
|
+
environment.reportSyncEnd(syncEndOf(request, problem, 'cancel'));
|
|
117
|
+
throw error instanceof ProblemError ? error : new ProblemError(problem);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=run-job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-job.js","sourceRoot":"","sources":["../../src/jobs/run-job.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KernelApiServices } from './kernel-api-services.ts';
|
|
2
|
+
import type { KernelRegistrations } from './kernel-registrations.ts';
|
|
3
|
+
export declare function registerExtensionsApi(api: KernelRegistrations, { registry, extensions }: KernelApiServices): void;
|
|
4
|
+
//# sourceMappingURL=extensions-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions-api.d.ts","sourceRoot":"","sources":["../../src/kernel-api/extensions-api.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA2BrE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,mBAAmB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,iBAAiB,GAAG,IAAI,CAQjH"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { kernelQuerySchemas } from '@kvman/sdk';
|
|
2
|
+
import { jsonSchemaOf } from "./json-schemas.js";
|
|
3
|
+
// `kernel.extensions.list` (plan 02 §2.12, ADR 0009, 28): the run's extensions, not the kernel, with everything they
|
|
4
|
+
// register, private names too. `kernel.registrations.list` (ADR 0011, 25) is the light form: one row per command and
|
|
5
|
+
// query, with no schema, for a caller that only needs to know what exists and whose it is.
|
|
6
|
+
function describe(registry, extension) {
|
|
7
|
+
const jobs = [...registry.jobs.values()].filter((job) => job.owner === extension.name);
|
|
8
|
+
const info = (kind) => jobs
|
|
9
|
+
.filter((job) => job.kind === kind)
|
|
10
|
+
.map((job) => ({ name: job.name, description: job.description, public: job.public, input: jsonSchemaOf(job.input, 'input'), output: jsonSchemaOf(job.output, 'output') }));
|
|
11
|
+
return {
|
|
12
|
+
name: extension.name,
|
|
13
|
+
version: extension.version,
|
|
14
|
+
source: extension.source,
|
|
15
|
+
revision: extension.revision,
|
|
16
|
+
namespace: extension.namespace,
|
|
17
|
+
commands: info('command'),
|
|
18
|
+
queries: info('query'),
|
|
19
|
+
settings: [...registry.settings.values()]
|
|
20
|
+
.filter((setting) => setting.extension === extension.name)
|
|
21
|
+
.map((setting) => ({ key: setting.key, description: setting.description, scopes: [...setting.scopes] })),
|
|
22
|
+
handlers: registry.handlers.filter((handler) => handler.owner === extension.name).map((handler) => ({ point: handler.point, description: handler.description })),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function registerExtensionsApi(api, { registry, extensions }) {
|
|
26
|
+
api.query('kernel.extensions.list', kernelQuerySchemas['kernel.extensions.list'], 'Lists the extensions of this run and what they register.', () => extensions.map((extension) => describe(registry, extension)));
|
|
27
|
+
api.query('kernel.registrations.list', kernelQuerySchemas['kernel.registrations.list'], 'Lists every command and query of this run with its owner, without schemas.', () => {
|
|
28
|
+
const loaded = new Set(extensions.map((extension) => extension.name));
|
|
29
|
+
return [...registry.jobs.values()].filter((job) => loaded.has(job.owner)).map((job) => ({ name: job.name, kind: job.kind, extension: job.owner, public: job.public, description: job.description }));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=extensions-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions-api.js","sourceRoot":"","sources":["../../src/kernel-api/extensions-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KernelApiServices } from './kernel-api-services.ts';
|
|
2
|
+
import type { KernelRegistrations } from './kernel-registrations.ts';
|
|
3
|
+
export declare function registerFolderApi(api: KernelRegistrations, services: KernelApiServices): void;
|
|
4
|
+
//# sourceMappingURL=folder-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-api.d.ts","sourceRoot":"","sources":["../../src/kernel-api/folder-api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAyBrE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAwB7F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { mkdir, readdir, realpath, stat } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { kernelCommandSchemas, kernelQuerySchemas } from '@kvman/sdk';
|
|
4
|
+
import { kernelProblem } from "../problems.js";
|
|
5
|
+
import { folderNameProblem } from "./folder-name.js";
|
|
6
|
+
// `kernel.folder.list` and `kernel.folder.create` (plan 02 §2.12, ADR 0009, 219, 222, and 223): the sub-folders of a folder,
|
|
7
|
+
// for choosing a workspace folder, and one new folder inside one. Listing reads names and nothing else; creating makes a
|
|
8
|
+
// single folder and records nothing.
|
|
9
|
+
const folderLimit = 1000;
|
|
10
|
+
const unreadable = (folder, error) => kernelProblem('VALIDATION_FAILED', `The folder can't be read (${error instanceof Error ? error.message : String(error)}).`, { path: folder });
|
|
11
|
+
async function realFolder(folder) {
|
|
12
|
+
if (!path.isAbsolute(folder))
|
|
13
|
+
throw kernelProblem('VALIDATION_FAILED', 'A folder path must be absolute.', { path: folder });
|
|
14
|
+
const real = await realpath(folder).catch((error) => {
|
|
15
|
+
throw unreadable(folder, error);
|
|
16
|
+
});
|
|
17
|
+
if (!(await stat(real)).isDirectory())
|
|
18
|
+
throw kernelProblem('VALIDATION_FAILED', 'A folder path must be a folder.', { path: folder });
|
|
19
|
+
return real;
|
|
20
|
+
}
|
|
21
|
+
async function isFolder(entry, location) {
|
|
22
|
+
if (entry.isDirectory())
|
|
23
|
+
return true;
|
|
24
|
+
if (!entry.isSymbolicLink())
|
|
25
|
+
return false;
|
|
26
|
+
return stat(location).then((found) => found.isDirectory(), () => false);
|
|
27
|
+
}
|
|
28
|
+
export function registerFolderApi(api, services) {
|
|
29
|
+
api.query('kernel.folder.list', kernelQuerySchemas['kernel.folder.list'], 'Lists the sub-folders of a folder on this machine.', async (input) => {
|
|
30
|
+
const folder = await realFolder(input.path ?? services.homeFolder);
|
|
31
|
+
const entries = await readdir(folder, { withFileTypes: true }).catch((error) => {
|
|
32
|
+
throw unreadable(folder, error);
|
|
33
|
+
});
|
|
34
|
+
const shown = entries.filter((entry) => input.hidden === true || !entry.name.startsWith('.')).sort((first, second) => first.name.localeCompare(second.name));
|
|
35
|
+
const checked = await Promise.all(shown.map(async (entry) => ({ entry, folder: await isFolder(entry, path.join(folder, entry.name)) })));
|
|
36
|
+
const folders = checked.filter((found) => found.folder).map(({ entry }) => ({ name: entry.name, path: path.join(folder, entry.name) }));
|
|
37
|
+
const parent = path.dirname(folder);
|
|
38
|
+
return { path: folder, parent: parent === folder ? null : parent, folders: folders.slice(0, folderLimit), truncated: folders.length > folderLimit };
|
|
39
|
+
});
|
|
40
|
+
api.command('kernel.folder.create', kernelCommandSchemas['kernel.folder.create'], 'Makes a folder inside a folder on this machine.', async (input) => {
|
|
41
|
+
const name = input.name.trim();
|
|
42
|
+
const reason = folderNameProblem(name);
|
|
43
|
+
if (reason !== undefined)
|
|
44
|
+
throw kernelProblem('VALIDATION_FAILED', reason, { name });
|
|
45
|
+
const parent = await realFolder(input.path);
|
|
46
|
+
const made = path.join(parent, name);
|
|
47
|
+
await mkdir(made).catch((error) => {
|
|
48
|
+
const exists = error instanceof Error && 'code' in error && error.code === 'EEXIST';
|
|
49
|
+
throw kernelProblem('VALIDATION_FAILED', exists ? `A folder or file named ${name} already exists here.` : `The folder can't be made (${error instanceof Error ? error.message : String(error)}).`, { path: made });
|
|
50
|
+
});
|
|
51
|
+
return { path: await realpath(made) };
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=folder-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-api.js","sourceRoot":"","sources":["../../src/kernel-api/folder-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-name.d.ts","sourceRoot":"","sources":["../../src/kernel-api/folder-name.ts"],"names":[],"mappings":"AAOA,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,GAAG,SAAS,CAUhH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// What a folder name may be (plan 02 §2.12, ADR 0009, 222): one name, never a path. The rules of each system are here, with
|
|
2
|
+
// a branch per platform: Windows refuses more than the others.
|
|
3
|
+
const nameLimit = 255;
|
|
4
|
+
const windowsForbidden = /[<>:"|?*\u0000-\u001f]/u;
|
|
5
|
+
const windowsDevice = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/iu;
|
|
6
|
+
/** Why `name` can't be a folder name on `platform`, or `undefined` when it can. */
|
|
7
|
+
export function folderNameProblem(name, platform = process.platform) {
|
|
8
|
+
if (name.trim() === '')
|
|
9
|
+
return "A folder name can't be empty.";
|
|
10
|
+
if (name.length > nameLimit)
|
|
11
|
+
return `A folder name is at most ${String(nameLimit)} characters.`;
|
|
12
|
+
if (/[/\\\u0000]/u.test(name))
|
|
13
|
+
return 'A folder name is one name, with no / or \\.';
|
|
14
|
+
if (name === '.' || name === '..')
|
|
15
|
+
return `A folder can't be named ${name}.`;
|
|
16
|
+
if (platform !== 'win32')
|
|
17
|
+
return undefined;
|
|
18
|
+
if (windowsForbidden.test(name))
|
|
19
|
+
return 'A folder name on Windows has none of < > : " | ? * or control characters.';
|
|
20
|
+
if (/[. ]$/u.test(name))
|
|
21
|
+
return "A folder name on Windows doesn't end in a dot or a space.";
|
|
22
|
+
if (windowsDevice.test(name))
|
|
23
|
+
return `${name} is a reserved name on Windows.`;
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=folder-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder-name.js","sourceRoot":"","sources":["../../src/kernel-api/folder-name.ts"],"names":[],"mappings":"AAAA,4HAA4H;AAC5H,+DAA+D;AAE/D,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AACnD,MAAM,aAAa,GAAG,oDAAoD,CAAC;AAE3E,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,WAA4B,OAAO,CAAC,QAAQ;IAC1F,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,+BAA+B,CAAC;IAC/D,IAAI,IAAI,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,4BAA4B,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC;IAChG,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,6CAA6C,CAAC;IACpF,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,2BAA2B,IAAI,GAAG,CAAC;IAC7E,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,2EAA2E,CAAC;IACpH,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,2DAA2D,CAAC;IAC5F,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,IAAI,iCAAiC,CAAC;IAC9E,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KernelApiServices } from './kernel-api-services.ts';
|
|
2
|
+
import type { KernelRegistrations } from './kernel-registrations.ts';
|
|
3
|
+
export declare function registerHealthApi(api: KernelRegistrations, services: KernelApiServices): void;
|
|
4
|
+
//# sourceMappingURL=health-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-api.d.ts","sourceRoot":"","sources":["../../src/kernel-api/health-api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGrE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAK7F"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { healthSchema, kernelQuerySchemas } from '@kvman/sdk';
|
|
2
|
+
import { listProcesses } from "../processes/process-rows.js";
|
|
3
|
+
// `kernel.health.get` (ADR 0009, 29), which the main thread answers since it knows the run, and `kernel.processes.list`.
|
|
4
|
+
export function registerHealthApi(api, services) {
|
|
5
|
+
api.query('kernel.health.get', kernelQuerySchemas['kernel.health.get'], 'Describes the running kvman.', async () => healthSchema.parse(await services.request({ kind: 'health' })));
|
|
6
|
+
api.query('kernel.processes.list', kernelQuerySchemas['kernel.processes.list'], 'Lists the running long-lived processes.', () => listProcesses(services.connection));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=health-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-api.js","sourceRoot":"","sources":["../../src/kernel-api/health-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAI7D,yHAAyH;AACzH,MAAM,UAAU,iBAAiB,CAAC,GAAwB,EAAE,QAA2B;IACrF,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,EAAE,KAAK,IAAI,EAAE,CACjH,YAAY,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAC/D,CAAC;IACF,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,uBAAuB,CAAC,EAAE,yCAAyC,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;AACvK,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { KernelApiServices } from './kernel-api-services.ts';
|
|
2
|
+
import type { KernelRegistrations } from './kernel-registrations.ts';
|
|
3
|
+
export declare function registerJobsFilesApi(api: KernelRegistrations, { connection, files }: KernelApiServices): void;
|
|
4
|
+
//# sourceMappingURL=jobs-files-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs-files-api.d.ts","sourceRoot":"","sources":["../../src/kernel-api/jobs-files-api.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAIrE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,mBAAmB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAAG,IAAI,CAgB7G"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { kernelCommandSchemas, kernelQuerySchemas } from '@kvman/sdk';
|
|
2
|
+
import { fileInWorkspace, unlinkAs } from "../files/file-access.js";
|
|
3
|
+
import { requireJob } from "../jobs/current-job.js";
|
|
4
|
+
import { listJobs, readJob } from "../jobs/job-rows.js";
|
|
5
|
+
// `kernel.jobs.*` and `kernel.files.*` (plan 02 §2.12, ADR 0009, 24): lists are the call's workspace, newest first; a job
|
|
6
|
+
// is found by id in any workspace, a file only in the call's.
|
|
7
|
+
export function registerJobsFilesApi(api, { connection, files }) {
|
|
8
|
+
api.query('kernel.jobs.get', kernelQuerySchemas['kernel.jobs.get'], 'Gets a job.', (input) => readJob(connection, input.id));
|
|
9
|
+
api.query('kernel.jobs.list', kernelQuerySchemas['kernel.jobs.list'], "Lists this workspace's jobs, newest first.", (input) => listJobs(connection, requireJob('kernel.jobs.list').workspace.id, input.status, input.limit));
|
|
10
|
+
api.query('kernel.files.get', kernelQuerySchemas['kernel.files.get'], 'Gets a file of this workspace.', (input) => fileInWorkspace(files, input.id, requireJob('kernel.files.get').workspace.id));
|
|
11
|
+
api.query('kernel.files.list', kernelQuerySchemas['kernel.files.list'], "Lists this workspace's files, newest first.", (input) => files.list(requireJob('kernel.files.list').workspace.id, input.limit));
|
|
12
|
+
api.command('kernel.files.unlink', kernelCommandSchemas['kernel.files.unlink'], 'Deletes a file of this workspace.', (input) => {
|
|
13
|
+
const job = requireJob('kernel.files.unlink');
|
|
14
|
+
unlinkAs(files, input.id, job.workspace.id, job.caller);
|
|
15
|
+
return {};
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=jobs-files-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs-files-api.js","sourceRoot":"","sources":["../../src/kernel-api/jobs-files-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAIxD,0HAA0H;AAC1H,8DAA8D;AAC9D,MAAM,UAAU,oBAAoB,CAAC,GAAwB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAqB;IACrG,GAAG,CAAC,KAAK,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7H,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,4CAA4C,EAAE,CAAC,KAAK,EAAE,EAAE,CAC5H,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAC7F,CAAC;IACF,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,gCAAgC,EAAE,CAAC,KAAK,EAAE,EAAE,CAChH,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAC9E,CAAC;IACF,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,EAAE,6CAA6C,EAAE,CAAC,KAAK,EAAE,EAAE,CAC/H,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CACtE,CAAC;IACF,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,qBAAqB,CAAC,EAAE,mCAAmC,EAAE,CAAC,KAAK,EAAE,EAAE;QAC7H,MAAM,GAAG,GAAG,UAAU,CAAC,qBAAqB,CAAC,CAAC;QAC9C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACxD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schemas.d.ts","sourceRoot":"","sources":["../../src/kernel-api/json-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,CAAC,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAUpE,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAO5F"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsonSchemaDocumentSchema, z } from '@kvman/sdk';
|
|
2
|
+
// A registration's schemas never change once its extension has loaded, and `kernel.extensions.list` and
|
|
3
|
+
// `kernel.settings.list` describe every one of them on each call, so a conversion is kept with its schema.
|
|
4
|
+
const converted = new WeakMap();
|
|
5
|
+
// A zod schema as JSON Schema, for forms (ADR 0009, 23): inputs and settings in zod's `input` mode, outputs in its
|
|
6
|
+
// `output` mode; a part JSON Schema can't express becomes `{}`.
|
|
7
|
+
export function jsonSchemaOf(schema, io) {
|
|
8
|
+
const known = converted.get(schema) ?? {};
|
|
9
|
+
const found = known[io];
|
|
10
|
+
if (found !== undefined)
|
|
11
|
+
return found;
|
|
12
|
+
const document = jsonSchemaDocumentSchema.parse(z.toJSONSchema(schema, { io, unrepresentable: 'any' }));
|
|
13
|
+
converted.set(schema, { ...known, [io]: document });
|
|
14
|
+
return document;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=json-schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schemas.js","sourceRoot":"","sources":["../../src/kernel-api/json-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,CAAC,EAAa,MAAM,YAAY,CAAC;AAIpE,wGAAwG;AACxG,2GAA2G;AAC3G,MAAM,SAAS,GAAG,IAAI,OAAO,EAAwB,CAAC;AAEtD,mHAAmH;AACnH,gEAAgE;AAChE,MAAM,UAAU,YAAY,CAAC,MAAiB,EAAE,EAAsB;IACpE,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IACxB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACxG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Files } from '../files/files.ts';
|
|
2
|
+
import type { Registry } from '../jobs/registry.ts';
|
|
3
|
+
import type { SecretsFile } from '../secrets/secrets-file.ts';
|
|
4
|
+
import type { Settings } from '../settings/settings.ts';
|
|
5
|
+
import type { Connection } from '../storage/database.ts';
|
|
6
|
+
import type { WorkerExtension, WorkerRequest } from '../workers/protocol.ts';
|
|
7
|
+
export type KernelApiServices = {
|
|
8
|
+
connection: Connection;
|
|
9
|
+
homeFolder: string;
|
|
10
|
+
registry: Registry;
|
|
11
|
+
settings: Settings;
|
|
12
|
+
secrets: SecretsFile;
|
|
13
|
+
files: Files;
|
|
14
|
+
extensions: readonly WorkerExtension[];
|
|
15
|
+
request: (request: WorkerRequest) => Promise<unknown>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=kernel-api-services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-api-services.d.ts","sourceRoot":"","sources":["../../src/kernel-api/kernel-api-services.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IACvC,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-api-services.js","sourceRoot":"","sources":["../../src/kernel-api/kernel-api-services.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from '@kvman/sdk';
|
|
2
|
+
import { type Owner, type Registry } from '../jobs/registry.ts';
|
|
3
|
+
export declare const kernelOwner: Owner;
|
|
4
|
+
type Handle<Input extends z.ZodType, Output extends z.ZodType> = (input: z.output<Input>) => z.input<Output> | Promise<z.input<Output>>;
|
|
5
|
+
export type KernelRegistrations = {
|
|
6
|
+
command<Input extends z.ZodType, Output extends z.ZodType>(name: string, schemas: {
|
|
7
|
+
input: Input;
|
|
8
|
+
output: Output;
|
|
9
|
+
}, description: string, handle: Handle<Input, Output>, options?: {
|
|
10
|
+
syncOnly: boolean;
|
|
11
|
+
}): void;
|
|
12
|
+
query<Input extends z.ZodType, Output extends z.ZodType>(name: string, schemas: {
|
|
13
|
+
input: Input;
|
|
14
|
+
output: Output;
|
|
15
|
+
}, description: string, handle: Handle<Input, Output>): void;
|
|
16
|
+
};
|
|
17
|
+
export declare function kernelRegistrations(registry: Registry): KernelRegistrations;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=kernel-registrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-registrations.d.ts","sourceRoot":"","sources":["../../src/kernel-api/kernel-registrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAM7E,eAAO,MAAM,WAAW,EAAE,KAAsD,CAAC;AAKjF,KAAK,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAExI,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,CAAC,OAAO,EACvD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACzC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAC7B,OAAO,CAAC,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,GAC9B,IAAI,CAAC;IACR,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7K,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,mBAAmB,CAO3E"}
|