@hraness/sponge 0.2.6 → 0.3.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/README.md +21 -9
- package/bin/sponge.js +8 -7
- package/dist/contracts/index.js +24 -6
- package/dist/contracts/validate.js +106 -29
- package/dist/migrations/008.d.ts +3 -0
- package/dist/migrations/008.js +5 -0
- package/dist/migrations/009.d.ts +3 -0
- package/dist/migrations/009.js +8 -0
- package/dist/migrations/010.d.ts +3 -0
- package/dist/migrations/010.js +11 -0
- package/dist/migrations/index.d.ts +15 -0
- package/dist/migrations/index.js +39 -0
- package/dist/src/acquisition/capture.js +87 -28
- package/dist/src/acquisition/cleanup.d.ts +0 -4
- package/dist/src/acquisition/cleanup.js +3 -5
- package/dist/src/acquisition/errors.js +17 -2
- package/dist/src/acquisition/files.d.ts +0 -1
- package/dist/src/acquisition/files.js +14 -11
- package/dist/src/acquisition/index.d.ts +2 -3
- package/dist/src/acquisition/index.js +1 -2
- package/dist/src/acquisition/lock.js +1 -1
- package/dist/src/acquisition/normalize.js +57 -18
- package/dist/src/acquisition/pins.js +22 -4
- package/dist/src/acquisition/process.js +67 -29
- package/dist/src/acquisition/runtime.d.ts +5 -7
- package/dist/src/acquisition/runtime.js +129 -68
- package/dist/src/acquisition/verify-helper.js +10 -3
- package/dist/src/annotations/quote.js +40 -12
- package/dist/src/annotations/store.d.ts +0 -1
- package/dist/src/annotations/store.js +66 -14
- package/dist/src/app/article.d.ts +2 -1
- package/dist/src/app/article.js +66 -70
- package/dist/src/app/bundle-files.d.ts +0 -4
- package/dist/src/app/bundle-files.js +11 -14
- package/dist/src/app/markdown.js +18 -6
- package/dist/src/app/source.d.ts +0 -4
- package/dist/src/app/source.js +18 -14
- package/dist/src/cli/arguments.d.ts +2 -8
- package/dist/src/cli/arguments.js +67 -80
- package/dist/src/cli/commands.d.ts +42 -0
- package/dist/src/cli/commands.js +795 -0
- package/dist/src/cli/config.js +12 -9
- package/dist/src/cli/digest.d.ts +1 -1
- package/dist/src/cli/digest.js +38 -16
- package/dist/src/cli/import.js +25 -4
- package/dist/src/cli/indexing.d.ts +2 -0
- package/dist/src/cli/indexing.js +26 -9
- package/dist/src/cli/main.js +47 -386
- package/dist/src/cli/portability.d.ts +0 -2
- package/dist/src/cli/portability.js +13 -8
- package/dist/src/cli/queue.js +12 -8
- package/dist/src/cli/runtimes.d.ts +1 -3
- package/dist/src/cli/runtimes.js +13 -6
- package/dist/src/cli/terminal.js +1 -1
- package/dist/src/cli/worker.d.ts +7 -0
- package/dist/src/cli/worker.js +54 -15
- package/dist/src/derivations/kinds.d.ts +34 -0
- package/dist/src/derivations/kinds.js +14 -0
- package/dist/src/derivations/types.d.ts +48 -0
- package/dist/src/derivations/types.js +1 -0
- package/dist/src/digest/derivation.d.ts +25 -0
- package/dist/src/digest/derivation.js +124 -0
- package/dist/src/digest/editorial.d.ts +9 -46
- package/dist/src/digest/editorial.js +57 -49
- package/dist/src/digest/endpoint.js +63 -27
- package/dist/src/digest/pipeline.d.ts +49 -28
- package/dist/src/digest/pipeline.js +343 -100
- package/dist/src/digest/schema.d.ts +11 -25
- package/dist/src/digest/schema.js +86 -18
- package/dist/src/errors.d.ts +46 -0
- package/dist/src/errors.js +117 -0
- package/dist/src/identity/query-policy.d.ts +0 -5
- package/dist/src/identity/query-policy.js +61 -9
- package/dist/src/identity/uri.d.ts +6 -5
- package/dist/src/identity/uri.js +37 -18
- package/dist/src/identity/visibility.d.ts +11 -1
- package/dist/src/identity/visibility.js +81 -17
- package/dist/src/importers/apply.js +104 -36
- package/dist/src/importers/custody.js +27 -9
- package/dist/src/importers/inspect.js +125 -38
- package/dist/src/importers/jungle-digest.d.ts +3 -6
- package/dist/src/importers/jungle-digest.js +196 -69
- package/dist/src/importers/jungle-store.d.ts +15 -6
- package/dist/src/importers/jungle-store.js +122 -28
- package/dist/src/importers/jungle.d.ts +14 -14
- package/dist/src/importers/jungle.js +136 -31
- package/dist/src/importers/manifest.js +57 -21
- package/dist/src/importers/verify-helper.js +18 -4
- package/dist/src/indexing/image.js +29 -10
- package/dist/src/indexing/index.d.ts +37 -6
- package/dist/src/indexing/index.js +360 -124
- package/dist/src/indexing/jobs.js +156 -47
- package/dist/src/indexing/prune-run.d.ts +2 -0
- package/dist/src/indexing/prune-run.js +69 -26
- package/dist/src/indexing/prune.d.ts +12 -3
- package/dist/src/indexing/prune.js +85 -35
- package/dist/src/indexing/runner.d.ts +2 -1
- package/dist/src/indexing/runner.js +83 -40
- package/dist/src/indexing/upgrade.d.ts +9 -0
- package/dist/src/indexing/upgrade.js +79 -0
- package/dist/src/inference/asr/bridge.js +6 -2
- package/dist/src/inference/asr/protocol.js +109 -19
- package/dist/src/inference/asr/runtime.js +58 -21
- package/dist/src/inference/asr/windows.js +9 -5
- package/dist/src/inference/embedding/index.d.ts +2 -6
- package/dist/src/inference/embedding/index.js +89 -29
- package/dist/src/ingest/attempt.d.ts +29 -0
- package/dist/src/ingest/attempt.js +55 -0
- package/dist/src/media/capture-helper.js +7 -2
- package/dist/src/media/capture.d.ts +2 -1
- package/dist/src/media/capture.js +124 -43
- package/dist/src/media/handler.d.ts +4 -2
- package/dist/src/media/handler.js +88 -70
- package/dist/src/media/transcribe.js +63 -21
- package/dist/src/metadata/article.js +49 -17
- package/dist/src/models/artifacts.d.ts +10 -8
- package/dist/src/models/artifacts.js +237 -106
- package/dist/src/models/catalog.d.ts +2 -5
- package/dist/src/models/catalog.js +94 -25
- package/dist/src/models/download.js +55 -15
- package/dist/src/models/runtime.d.ts +0 -2
- package/dist/src/models/runtime.js +69 -33
- package/dist/src/pdf/capture-helper.js +3 -1
- package/dist/src/pdf/capture.d.ts +2 -1
- package/dist/src/pdf/capture.js +95 -27
- package/dist/src/pdf/errors.js +12 -1
- package/dist/src/pdf/handler.d.ts +2 -1
- package/dist/src/pdf/handler.js +70 -71
- package/dist/src/pdf/index.d.ts +1 -3
- package/dist/src/pdf/index.js +0 -2
- package/dist/src/pdf/input.js +12 -7
- package/dist/src/pdf/normalize.js +80 -21
- package/dist/src/pdf/source-identity.js +3 -2
- package/dist/src/pdf/source.js +12 -8
- package/dist/src/pdf/verify-helper.js +15 -3
- package/dist/src/portability/backup.d.ts +2 -9
- package/dist/src/portability/backup.js +106 -22
- package/dist/src/portability/database.js +51 -17
- package/dist/src/portability/export.js +35 -9
- package/dist/src/portability/files.d.ts +1 -4
- package/dist/src/portability/files.js +127 -67
- package/dist/src/portability/gc.js +65 -22
- package/dist/src/publish/component.js +1 -1
- package/dist/src/publish/feed.d.ts +2 -2
- package/dist/src/publish/feed.js +75 -29
- package/dist/src/publish/identity.d.ts +5 -1
- package/dist/src/publish/identity.js +31 -11
- package/dist/src/publish/index.d.ts +2 -3
- package/dist/src/publish/index.js +34 -21
- package/dist/src/publish/projection.d.ts +2 -9
- package/dist/src/publish/projection.js +21 -14
- package/dist/src/search/extension.js +3 -1
- package/dist/src/search/hybrid.d.ts +3 -8
- package/dist/src/search/hybrid.js +45 -11
- package/dist/src/search/lexical.js +18 -4
- package/dist/src/search/query.js +56 -25
- package/dist/src/search/vector.js +37 -10
- package/dist/src/service/launch-agent.d.ts +5 -3
- package/dist/src/service/launch-agent.js +272 -83
- package/dist/src/service/lifetime.js +47 -14
- package/dist/src/service/loop.d.ts +3 -3
- package/dist/src/service/loop.js +47 -19
- package/dist/src/store/annotations.d.ts +32 -0
- package/dist/src/store/annotations.js +44 -0
- package/dist/src/store/backups.d.ts +18 -0
- package/dist/src/store/backups.js +110 -0
- package/dist/src/store/blobs.d.ts +24 -0
- package/dist/src/store/blobs.js +139 -0
- package/dist/src/store/changes.d.ts +5 -12
- package/dist/src/store/changes.js +108 -56
- package/dist/src/store/context.d.ts +15 -0
- package/dist/src/store/context.js +19 -0
- package/dist/src/store/derivations.d.ts +42 -0
- package/dist/src/store/derivations.js +104 -0
- package/dist/src/store/files.d.ts +0 -2
- package/dist/src/store/files.js +19 -24
- package/dist/src/store/ids.d.ts +30 -0
- package/dist/src/store/ids.js +34 -0
- package/dist/src/store/imports.d.ts +26 -0
- package/dist/src/store/imports.js +57 -0
- package/dist/src/store/index.d.ts +3 -186
- package/dist/src/store/index.js +2 -809
- package/dist/src/store/lease.d.ts +20 -0
- package/dist/src/store/lease.js +62 -0
- package/dist/src/store/library.d.ts +75 -0
- package/dist/src/store/library.js +174 -0
- package/dist/src/store/open.d.ts +7 -0
- package/dist/src/store/open.js +183 -0
- package/dist/src/store/queue.d.ts +65 -0
- package/dist/src/store/queue.js +327 -0
- package/dist/src/store/revisions.d.ts +12 -0
- package/dist/src/store/revisions.js +189 -0
- package/dist/src/store/search-index.d.ts +63 -0
- package/dist/src/store/search-index.js +190 -0
- package/dist/src/store/sync-ready.d.ts +6 -0
- package/dist/src/store/sync-ready.js +121 -0
- package/dist/src/store/types.d.ts +1 -5
- package/dist/src/store/types.js +1 -8
- package/dist/src/util/canonical.d.ts +2 -0
- package/dist/src/util/canonical.js +17 -0
- package/dist/src/util/exact.d.ts +2 -0
- package/dist/src/util/exact.js +9 -0
- package/dist/src/util/fsync.d.ts +4 -0
- package/dist/src/util/fsync.js +22 -0
- package/dist/src/util/hash.d.ts +4 -0
- package/dist/src/util/hash.js +8 -0
- package/dist/src/worker/basic.d.ts +0 -1
- package/dist/src/worker/basic.js +23 -7
- package/dist/src/worker/custody.d.ts +4 -1
- package/dist/src/worker/custody.js +111 -38
- package/dist/src/worker/engine.d.ts +2 -1
- package/dist/src/worker/engine.js +42 -20
- package/dist/src/worker/identity.js +13 -5
- package/dist/src/worker/journal.d.ts +1 -1
- package/dist/src/worker/journal.js +54 -24
- package/dist/src/worker/lock.d.ts +18 -0
- package/dist/src/worker/lock.js +196 -0
- package/dist/src/worker/runtime-gc.d.ts +4 -3
- package/dist/src/worker/runtime-gc.js +68 -41
- package/dist/src/worker/supervisor-child.js +19 -6
- package/dist/src/worker/supervisor.js +41 -8
- package/native/runtime-manifest.json +4 -4
- package/package.json +10 -2
- package/dist/src/digest/store.d.ts +0 -57
- package/dist/src/digest/store.js +0 -79
- package/dist/src/store/foundation.d.ts +0 -7
- package/dist/src/store/foundation.js +0 -7
|
@@ -1,43 +1,79 @@
|
|
|
1
1
|
import { dirname, isAbsolute, join } from 'node:path';
|
|
2
2
|
import { realpath, lstat } from 'node:fs/promises';
|
|
3
|
-
import { readConfined
|
|
3
|
+
import { readConfined } from '../acquisition/files.js';
|
|
4
|
+
import { sha256 as hash } from '../util/hash.js';
|
|
4
5
|
import { object } from '../acquisition/normalize.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import { SpongeError } from '../errors.js';
|
|
7
|
+
function bounded(value, max) {
|
|
8
|
+
if (typeof value !== 'string' || !value || Buffer.byteLength(value) > max || value.includes('\0'))
|
|
9
|
+
throw new SpongeError('invalid-input');
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function keys(value, allowed) {
|
|
13
|
+
if (Object.keys(value).some((k) => !allowed.includes(k)))
|
|
14
|
+
throw new SpongeError('invalid-input');
|
|
15
|
+
}
|
|
16
|
+
function parseJson(bytes) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(bytes.toString('utf8'));
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new SpongeError('invalid-input', { cause: error });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
9
24
|
/** Explicit local source manifest; no recursive discovery or implicit public selection. */
|
|
10
25
|
export async function readImportManifest(path) {
|
|
11
|
-
if (!isAbsolute(path) || await realpath(path) !== path)
|
|
12
|
-
throw
|
|
13
|
-
const root = dirname(path), bytes = await readConfined(root, path.slice(root.length + 1), 1024 ** 2), raw = object(
|
|
26
|
+
if (!isAbsolute(path) || (await realpath(path)) !== path)
|
|
27
|
+
throw new SpongeError('invalid-input');
|
|
28
|
+
const root = dirname(path), bytes = await readConfined(root, path.slice(root.length + 1), 1024 ** 2), raw = object(parseJson(bytes));
|
|
14
29
|
keys(raw, ['schemaVersion', 'namespace', 'entries']);
|
|
15
30
|
if (raw.schemaVersion !== 1 || !Array.isArray(raw.entries) || raw.entries.length > 1000)
|
|
16
|
-
throw
|
|
31
|
+
throw new SpongeError('unsupported');
|
|
17
32
|
const namespace = bounded(raw.namespace, 128);
|
|
18
33
|
if (!/^[A-Za-z0-9_.-]+$/.test(namespace))
|
|
19
|
-
throw
|
|
34
|
+
throw new SpongeError('invalid-input');
|
|
20
35
|
const ids = new Set();
|
|
21
|
-
const entries = raw.entries.map(value => {
|
|
36
|
+
const entries = raw.entries.map((value) => {
|
|
22
37
|
const entry = object(value);
|
|
23
38
|
keys(entry, ['id', 'bundle', 'privacy', 'notes', 'readingState']);
|
|
24
39
|
const id = bounded(entry.id, 256), bundle = bounded(entry.bundle, 4096);
|
|
25
|
-
if (ids.has(id) ||
|
|
26
|
-
|
|
40
|
+
if (ids.has(id) ||
|
|
41
|
+
isAbsolute(bundle) ||
|
|
42
|
+
bundle.includes('\\') ||
|
|
43
|
+
bundle.split('/').some((p) => !p || p === '.' || p === '..') ||
|
|
44
|
+
!['private', 'published'].includes(String(entry.privacy)))
|
|
45
|
+
throw new SpongeError('invalid-input');
|
|
27
46
|
ids.add(id);
|
|
28
47
|
if (entry.notes !== undefined && !Array.isArray(entry.notes))
|
|
29
|
-
throw
|
|
48
|
+
throw new SpongeError('invalid-input');
|
|
30
49
|
const noteIds = new Set();
|
|
31
|
-
const notes = (entry.notes ?? []).map(value => {
|
|
32
|
-
|
|
50
|
+
const notes = (entry.notes ?? []).map((value) => {
|
|
51
|
+
const note = object(value);
|
|
52
|
+
keys(note, ['id', 'body']);
|
|
53
|
+
const id = bounded(note.id, 256), body = bounded(note.body, 65536);
|
|
54
|
+
if (noteIds.has(id))
|
|
55
|
+
throw new SpongeError('invalid-input');
|
|
56
|
+
noteIds.add(id);
|
|
57
|
+
return { id, body };
|
|
58
|
+
});
|
|
33
59
|
if (notes.length > 100)
|
|
34
|
-
throw
|
|
60
|
+
throw new SpongeError('limit-exceeded');
|
|
35
61
|
const readingState = entry.readingState === undefined ? undefined : object(entry.readingState);
|
|
36
62
|
if (readingState && Buffer.byteLength(JSON.stringify(readingState)) > 65536)
|
|
37
|
-
throw
|
|
38
|
-
return {
|
|
63
|
+
throw new SpongeError('limit-exceeded');
|
|
64
|
+
return {
|
|
65
|
+
id,
|
|
66
|
+
bundle,
|
|
67
|
+
privacy: entry.privacy,
|
|
68
|
+
notes,
|
|
69
|
+
...(readingState ? { readingState } : {}),
|
|
70
|
+
};
|
|
39
71
|
});
|
|
40
72
|
return { root, manifest: { schemaVersion: 1, namespace, entries }, sha256: hash(bytes) };
|
|
41
73
|
}
|
|
42
|
-
export async function importBundleRoot(root, entry) {
|
|
43
|
-
|
|
74
|
+
export async function importBundleRoot(root, entry) {
|
|
75
|
+
const path = join(root, entry.bundle);
|
|
76
|
+
if ((await realpath(path)) !== path || (await lstat(path)).isSymbolicLink() || !(await lstat(path)).isDirectory())
|
|
77
|
+
throw new SpongeError('integrity');
|
|
78
|
+
return path;
|
|
79
|
+
}
|
|
@@ -1,27 +1,41 @@
|
|
|
1
|
+
import { SpongeError } from '../errors.js';
|
|
1
2
|
/** Only released Wordcell public verifiers, with no source or document text in output. */
|
|
2
3
|
const runtime = process.argv[2], bundle = process.argv[3], kind = process.argv[4];
|
|
3
4
|
try {
|
|
4
5
|
let result;
|
|
5
6
|
if (kind === 'pdf') {
|
|
6
7
|
const { verifyPdfCaptureBundle } = await import(import.meta.resolve('@hraness/wordcell/pdf', `${runtime}/package.json`));
|
|
7
|
-
result = await verifyPdfCaptureBundle(bundle, {
|
|
8
|
+
result = await verifyPdfCaptureBundle(bundle, {
|
|
9
|
+
maxDocumentBytes: 16 * 1024 ** 2,
|
|
10
|
+
maxSourceBytes: 100 * 1024 ** 2,
|
|
11
|
+
maxVerifiedAssets: 200,
|
|
12
|
+
maxAssetBytes: 20 * 1024 ** 2,
|
|
13
|
+
maxTotalAssetBytes: 500 * 1024 ** 2,
|
|
14
|
+
maxVerificationMs: 30000,
|
|
15
|
+
});
|
|
8
16
|
const { markdown, ...document } = result.inspection.markdown;
|
|
9
17
|
result = { ...result, inspection: { ...result.inspection, markdown: document } };
|
|
10
18
|
}
|
|
11
19
|
else {
|
|
12
20
|
const { verifyCaptureBundle } = await import(import.meta.resolve('@hraness/wordcell/clip/bundle-reader', `${runtime}/package.json`));
|
|
13
|
-
result = await verifyCaptureBundle(bundle, {
|
|
21
|
+
result = await verifyCaptureBundle(bundle, {
|
|
22
|
+
verifyAssets: true,
|
|
23
|
+
maxDocumentBytes: 16 * 1024 ** 2,
|
|
24
|
+
maxVerifiedAssets: 200,
|
|
25
|
+
maxAssetBytes: 20 * 1024 ** 2,
|
|
26
|
+
maxTotalAssetBytes: 500 * 1024 ** 2,
|
|
27
|
+
maxAssetVerificationMs: 30000,
|
|
28
|
+
});
|
|
14
29
|
const { markdown, ...document } = result.inspection.document;
|
|
15
30
|
const { metadata, ...inspection } = result.inspection;
|
|
16
31
|
result = { ...result, inspection: { ...inspection, document } };
|
|
17
32
|
}
|
|
18
33
|
const output = JSON.stringify(result);
|
|
19
34
|
if (Buffer.byteLength(output) > 65536)
|
|
20
|
-
throw
|
|
35
|
+
throw new SpongeError('limit-exceeded');
|
|
21
36
|
process.stdout.write(output);
|
|
22
37
|
}
|
|
23
38
|
catch {
|
|
24
39
|
process.stdout.write(JSON.stringify({ ok: false, code: 'unsupported' }));
|
|
25
40
|
process.exitCode = 1;
|
|
26
41
|
}
|
|
27
|
-
export {};
|
|
@@ -1,27 +1,46 @@
|
|
|
1
1
|
import { mkdtemp, writeFile, rm } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { privateRoot, readConfined
|
|
3
|
+
import { privateRoot, readConfined } from '../acquisition/files.js';
|
|
4
|
+
import { sha256 as hash } from '../util/hash.js';
|
|
4
5
|
import { runOwned } from '../acquisition/process.js';
|
|
5
|
-
import { encodeEmbeddingRequest
|
|
6
|
+
import { encodeEmbeddingRequest } from '../inference/embedding/index.js';
|
|
7
|
+
import { SpongeError } from '../errors.js';
|
|
6
8
|
/** Derived pixels are disposable; source image blobs remain unchanged. */
|
|
7
9
|
export async function deriveEmbeddingImage(bytes, options) {
|
|
8
10
|
if (process.platform !== 'darwin' || process.arch !== 'arm64')
|
|
9
|
-
throw new
|
|
11
|
+
throw new SpongeError('unsupported');
|
|
10
12
|
if (!bytes.length || bytes.length > 20 * 1024 ** 2)
|
|
11
|
-
throw new
|
|
13
|
+
throw new SpongeError('limit-exceeded');
|
|
12
14
|
const root = await privateRoot(options.scratchRoot), scratch = await mkdtemp(join(root, 'image-derive-'));
|
|
13
15
|
let settled = true;
|
|
14
16
|
try {
|
|
15
17
|
const input = join(scratch, 'source'), output = join(scratch, 'image.png');
|
|
16
18
|
await writeFile(input, bytes, { mode: 0o600, flag: 'wx' });
|
|
17
|
-
const run = async (args) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const run = async (args) => {
|
|
20
|
+
settled = false;
|
|
21
|
+
const result = await (options.runProcess ?? runOwned)('/usr/bin/sandbox-exec', ['-p', '(version 1) (allow default) (deny network*)', '/usr/bin/sips', ...args], {
|
|
22
|
+
env: { PATH: '/usr/bin:/bin', HOME: scratch, TMPDIR: scratch, LANG: 'C' },
|
|
23
|
+
deadlineMs: 30000,
|
|
24
|
+
maxOutputBytes: 65536,
|
|
25
|
+
signal: options.signal,
|
|
26
|
+
});
|
|
27
|
+
settled = result.cleanup === 'settled';
|
|
28
|
+
if (!settled)
|
|
29
|
+
throw new SpongeError('cleanup-required');
|
|
30
|
+
if (result.stopped)
|
|
31
|
+
throw new SpongeError(result.stopped);
|
|
32
|
+
if (result.code !== 0)
|
|
33
|
+
throw new SpongeError('unsupported');
|
|
34
|
+
return result.stdout;
|
|
35
|
+
};
|
|
21
36
|
const metadata = await run(['-g', 'pixelWidth', '-g', 'pixelHeight', input]);
|
|
22
37
|
const width = Number(metadata.match(/pixelWidth:\s*(\d+)/)?.[1]), height = Number(metadata.match(/pixelHeight:\s*(\d+)/)?.[1]);
|
|
23
|
-
if (!Number.isSafeInteger(width) ||
|
|
24
|
-
|
|
38
|
+
if (!Number.isSafeInteger(width) ||
|
|
39
|
+
!Number.isSafeInteger(height) ||
|
|
40
|
+
width < 1 ||
|
|
41
|
+
height < 1 ||
|
|
42
|
+
width * height > 40_000_000)
|
|
43
|
+
throw new SpongeError('limit-exceeded');
|
|
25
44
|
await run(['--resampleHeightWidthMax', '512', '--setProperty', 'format', 'png', input, '--out', output]);
|
|
26
45
|
const png = await readConfined(scratch, 'image.png', 2 * 1024 ** 2);
|
|
27
46
|
encodeEmbeddingRequest([{ kind: 'image', png }]);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
/** One embeddable source of a revision. `derivationHash` is its content key in the space: a document chunk's embedding input hash, or an image's source hash. */
|
|
2
3
|
export interface IndexInput {
|
|
3
4
|
sourceId: string;
|
|
4
5
|
revisionId: string;
|
|
@@ -15,14 +16,14 @@ export interface GenerationStatus {
|
|
|
15
16
|
fingerprint: string;
|
|
16
17
|
state: string;
|
|
17
18
|
revisionEpoch: number;
|
|
19
|
+
items: number;
|
|
18
20
|
expected: number;
|
|
19
21
|
completed: number;
|
|
22
|
+
pending: number;
|
|
20
23
|
profileId: string;
|
|
21
24
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
constructor(code: 'invalid-index' | 'stale-index' | 'incomplete-index' | 'cancelled-index');
|
|
25
|
-
}
|
|
25
|
+
/** Schema 10 keeps coverage in `index_items` and `index_inputs`; a generation whose JSON coverage could not be converted keeps it and never reads. */
|
|
26
|
+
export declare const coverageMarker = "{\"version\":2}";
|
|
26
27
|
export type VectorEncoding = 'f32' | 'int8';
|
|
27
28
|
/** Storage format follows the space identity: no `quantization` (legacy) or `f32` stores float32 LE; `int8-symmetric-maxabs-v1` stores one int8 code per dimension. */
|
|
28
29
|
export declare function spaceEncoding(identity: Record<string, unknown>): VectorEncoding;
|
|
@@ -30,9 +31,34 @@ export declare function spaceEncoding(identity: Record<string, unknown>): Vector
|
|
|
30
31
|
export declare function encodeVector(vector: readonly number[], encoding: VectorEncoding): Buffer;
|
|
31
32
|
/** Exact byte length, finite floats, int8 codes within [-127,127] and nonzero; int8 returns the unit dequantized vector. */
|
|
32
33
|
export declare function decodeVector(bytes: Uint8Array, dimensions: number, encoding: VectorEncoding): number[];
|
|
34
|
+
/** What one document chunk's vector was derived from before schema 10: its representation, position and text. Migrations 9 and 10 still read it. */
|
|
35
|
+
export declare const chunkHash: (representationId: string, ordinal: number, text: string) => string;
|
|
33
36
|
/** Unicode-safe chunks fit the fixed document prompt within the embedding text budget, preferring whitespace breaks. */
|
|
34
37
|
export declare function chunkDocument(text: string): string[];
|
|
35
|
-
/**
|
|
38
|
+
/** The helper's input hash of a document chunk: `encodeEmbeddingRequest([{kind:'document',text}]).inputHashes[0]` without its validation, so a commit never fails on text the embedder refuses. */
|
|
39
|
+
export declare function documentHash(text: string): string;
|
|
40
|
+
export declare const imageHash: (assetSha256: string) => string;
|
|
41
|
+
type Source = {
|
|
42
|
+
kind: 'document';
|
|
43
|
+
representationId: string;
|
|
44
|
+
ordinal: number;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'image';
|
|
47
|
+
assetSha256: string;
|
|
48
|
+
};
|
|
49
|
+
/** A source id is `[revisionId,'document',representationId,ordinal]` or `[revisionId,'image',assetSha256]`. */
|
|
50
|
+
export declare function parseSource(sourceId: string, revisionId: string): Source;
|
|
51
|
+
export declare const sourceInput: (row: Record<string, unknown>) => IndexInput;
|
|
52
|
+
/** Brings a building or active generation's coverage to the current revisions: inputs of refreshed or deleted items go, the
|
|
53
|
+
* new revision's come. Embeddings stay; an input is pending while its space has none for its content. Returns items changed. */
|
|
54
|
+
export declare function syncGeneration(db: DatabaseSync, id: string): number;
|
|
55
|
+
/** Queues a generation's index job again (or its first) unless it is queued, running or awaiting cleanup. */
|
|
56
|
+
export declare function armJob(db: DatabaseSync, id: string): void;
|
|
57
|
+
/** Inside the transaction that changed a current revision or deleted an item: every active generation, and every building one
|
|
58
|
+
* whose job is live, follows the library. An active generation with content to embed gets its job queued: only the delta runs. */
|
|
59
|
+
export declare function trackLibrary(db: DatabaseSync): void;
|
|
60
|
+
/** Identity must already be the verified embedder fingerprint. Existing identities are immutable. Every input whose content the
|
|
61
|
+
* space already embedded (an earlier generation, another item) is complete at once. */
|
|
36
62
|
export declare function createGeneration(db: DatabaseSync, options: {
|
|
37
63
|
profileId: string;
|
|
38
64
|
fingerprint: string;
|
|
@@ -40,7 +66,9 @@ export declare function createGeneration(db: DatabaseSync, options: {
|
|
|
40
66
|
dimensions: number;
|
|
41
67
|
}): GenerationStatus;
|
|
42
68
|
export declare function generationStatus(db: DatabaseSync, id: string): GenerationStatus;
|
|
69
|
+
/** One input per content hash still to embed, oldest coverage first: identical chunks embed once. */
|
|
43
70
|
export declare function pendingInputs(db: DatabaseSync, id: string, limit?: number): IndexInput[];
|
|
71
|
+
/** Stores each result's vector under its content hash in the space. A source dropped by a refresh or delete since it was read is skipped. */
|
|
44
72
|
export declare function writeBatch(db: DatabaseSync, id: string, fingerprint: string, batch: readonly {
|
|
45
73
|
sourceId: string;
|
|
46
74
|
revisionId: string;
|
|
@@ -48,8 +76,11 @@ export declare function writeBatch(db: DatabaseSync, id: string, fingerprint: st
|
|
|
48
76
|
inputHash: string;
|
|
49
77
|
vector: readonly number[];
|
|
50
78
|
}[]): void;
|
|
79
|
+
/** Complete and current: no pending input, and coverage names exactly the current revision of every live item. */
|
|
51
80
|
export declare function activateGeneration(db: DatabaseSync, id: string): GenerationStatus;
|
|
52
81
|
export declare function cancelGeneration(db: DatabaseSync, id: string): void;
|
|
82
|
+
/** The active generation of a profile, if any. */
|
|
83
|
+
export declare function activeGeneration(db: DatabaseSync, profileId: string): string | undefined;
|
|
53
84
|
/** Read-side join removes deleted/refreshed revisions even when an old generation stays active. */
|
|
54
85
|
export declare function activeVectors(db: DatabaseSync, profileId: string): {
|
|
55
86
|
fingerprint: string;
|
|
@@ -57,4 +88,4 @@ export declare function activeVectors(db: DatabaseSync, profileId: string): {
|
|
|
57
88
|
source: IndexInput;
|
|
58
89
|
vector: number[];
|
|
59
90
|
}[];
|
|
60
|
-
export
|
|
91
|
+
export {};
|