@fortemi/core 2026.9.0 → 2026.9.2
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 +9 -1
- package/dist/index.d.ts +84 -6
- package/dist/index.js +630 -375
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/schemas/source-note-upsert/contract.receipt.json +78 -0
- package/schemas/source-note-upsert/v1.conformance.json +100 -0
package/dist/index.js
CHANGED
|
@@ -2072,6 +2072,54 @@ var migration0023 = {
|
|
|
2072
2072
|
`
|
|
2073
2073
|
};
|
|
2074
2074
|
|
|
2075
|
+
// src/migrations/0024_source_upsert_contract.ts
|
|
2076
|
+
var migration0024 = {
|
|
2077
|
+
version: 24,
|
|
2078
|
+
name: "0024_source_upsert_contract",
|
|
2079
|
+
sql: `
|
|
2080
|
+
ALTER TABLE source_import_run ADD COLUMN IF NOT EXISTS external_run_id TEXT;
|
|
2081
|
+
ALTER TABLE source_import_run ADD COLUMN IF NOT EXISTS source_id TEXT;
|
|
2082
|
+
ALTER TABLE source_import_run ADD COLUMN IF NOT EXISTS source_schema_version TEXT;
|
|
2083
|
+
ALTER TABLE source_import_run ADD COLUMN IF NOT EXISTS workspace_id TEXT;
|
|
2084
|
+
UPDATE source_import_run SET external_run_id = id WHERE external_run_id IS NULL;
|
|
2085
|
+
UPDATE source_import_run SET source_schema_version = 'legacy' WHERE source_schema_version IS NULL;
|
|
2086
|
+
ALTER TABLE source_import_run ALTER COLUMN external_run_id SET NOT NULL;
|
|
2087
|
+
ALTER TABLE source_import_run ALTER COLUMN source_schema_version SET NOT NULL;
|
|
2088
|
+
ALTER TABLE source_import_run ADD CONSTRAINT source_import_run_contract_lengths
|
|
2089
|
+
CHECK (
|
|
2090
|
+
length(external_run_id) BETWEEN 1 AND 200
|
|
2091
|
+
AND (source_id IS NULL OR length(source_id) BETWEEN 1 AND 500)
|
|
2092
|
+
AND length(source_schema_version) BETWEEN 1 AND 100
|
|
2093
|
+
AND (workspace_id IS NULL OR length(workspace_id) BETWEEN 1 AND 500)
|
|
2094
|
+
);
|
|
2095
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_source_import_run_scope
|
|
2096
|
+
ON source_import_run(tenant_id, COALESCE(archive_id, ''), namespace, external_run_id);
|
|
2097
|
+
|
|
2098
|
+
ALTER TABLE source_identity ADD COLUMN IF NOT EXISTS source_id TEXT;
|
|
2099
|
+
ALTER TABLE source_identity ADD CONSTRAINT source_identity_source_id_length
|
|
2100
|
+
CHECK (source_id IS NULL OR length(source_id) BETWEEN 1 AND 500);
|
|
2101
|
+
|
|
2102
|
+
CREATE TABLE IF NOT EXISTS source_import_batch (
|
|
2103
|
+
id TEXT PRIMARY KEY,
|
|
2104
|
+
tenant_id TEXT NOT NULL DEFAULT 'default',
|
|
2105
|
+
archive_id TEXT,
|
|
2106
|
+
namespace TEXT NOT NULL,
|
|
2107
|
+
batch_id TEXT NOT NULL,
|
|
2108
|
+
request_digest TEXT NOT NULL,
|
|
2109
|
+
import_run_id TEXT NOT NULL,
|
|
2110
|
+
outcome TEXT NOT NULL,
|
|
2111
|
+
checkpoint JSONB NOT NULL DEFAULT '{}',
|
|
2112
|
+
receipt JSONB NOT NULL DEFAULT '{}',
|
|
2113
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
2114
|
+
);
|
|
2115
|
+
|
|
2116
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_source_import_batch_scope
|
|
2117
|
+
ON source_import_batch(tenant_id, COALESCE(archive_id, ''), namespace, batch_id);
|
|
2118
|
+
CREATE INDEX IF NOT EXISTS idx_source_import_batch_run
|
|
2119
|
+
ON source_import_batch(import_run_id);
|
|
2120
|
+
`
|
|
2121
|
+
};
|
|
2122
|
+
|
|
2075
2123
|
// src/migrations/index.ts
|
|
2076
2124
|
var allMigrations = [
|
|
2077
2125
|
migration0001,
|
|
@@ -2096,7 +2144,8 @@ var allMigrations = [
|
|
|
2096
2144
|
migration0020,
|
|
2097
2145
|
migration0021,
|
|
2098
2146
|
migration0022,
|
|
2099
|
-
migration0023
|
|
2147
|
+
migration0023,
|
|
2148
|
+
migration0024
|
|
2100
2149
|
];
|
|
2101
2150
|
|
|
2102
2151
|
// src/data-archive.ts
|
|
@@ -5461,52 +5510,79 @@ function createLazyBlobStore(archiveName, options) {
|
|
|
5461
5510
|
}
|
|
5462
5511
|
|
|
5463
5512
|
// src/repositories/source-upsert-repository.ts
|
|
5464
|
-
var
|
|
5513
|
+
var SOURCE_UPSERT_CONTRACT_VERSION = "1.0.0";
|
|
5514
|
+
var SOURCE_UPSERT_MAX_ITEMS = 500;
|
|
5465
5515
|
function assertSource(input) {
|
|
5466
|
-
if (!input.
|
|
5467
|
-
if (!input.
|
|
5468
|
-
if (!input.
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
if (!input.import_run_id || input.import_run_id.length > 128) throw new Error("Source import_run_id is required and must be <= 128 characters");
|
|
5516
|
+
if (!input.tenant_id || input.tenant_id.length > 200) throw new Error("invalid_batch_metadata");
|
|
5517
|
+
if (!input.namespace || input.namespace.length > 200) throw new Error("invalid_batch_metadata");
|
|
5518
|
+
if (!input.external_id || input.external_id.length > 1e3) throw new Error("invalid_item");
|
|
5519
|
+
if (!input.source_schema_version || input.source_schema_version.length > 100) throw new Error("invalid_batch_metadata");
|
|
5520
|
+
if (!input.import_run_id || input.import_run_id.length > 200) throw new Error("invalid_batch_metadata");
|
|
5472
5521
|
}
|
|
5473
|
-
function
|
|
5522
|
+
function sourceIdentityHash(source) {
|
|
5474
5523
|
return computeHash(new TextEncoder().encode([
|
|
5475
5524
|
source.tenant_id ?? "default",
|
|
5476
|
-
source.archive_id ?? "",
|
|
5525
|
+
source.archive_id ?? "public",
|
|
5477
5526
|
source.namespace,
|
|
5478
|
-
source.external_id
|
|
5527
|
+
source.external_id,
|
|
5528
|
+
""
|
|
5479
5529
|
].join("\0")));
|
|
5480
5530
|
}
|
|
5481
|
-
function
|
|
5531
|
+
function sourceContentDigest(content) {
|
|
5482
5532
|
return computeHash(new TextEncoder().encode(content));
|
|
5483
5533
|
}
|
|
5534
|
+
function sourceRequestDigest(items, options) {
|
|
5535
|
+
return computeHash(new TextEncoder().encode(JSON.stringify({
|
|
5536
|
+
items: items.map((item) => ({
|
|
5537
|
+
source: item.source,
|
|
5538
|
+
title: item.title ?? null,
|
|
5539
|
+
content: item.content,
|
|
5540
|
+
content_digest: item.content_digest ?? null,
|
|
5541
|
+
format: item.format ?? "markdown",
|
|
5542
|
+
visibility: item.visibility ?? "private",
|
|
5543
|
+
metadata: item.metadata ?? null,
|
|
5544
|
+
policy: item.policy ?? options.policy ?? "version"
|
|
5545
|
+
})),
|
|
5546
|
+
checkpoint: options.checkpoint ?? null,
|
|
5547
|
+
dry_run: options.dryRun === true
|
|
5548
|
+
})));
|
|
5549
|
+
}
|
|
5550
|
+
function deriveSourceBatchId(requestDigest) {
|
|
5551
|
+
return `derived-${requestDigest.slice("sha256:".length, "sha256:".length + 32)}`;
|
|
5552
|
+
}
|
|
5553
|
+
function sourceRunRecordId(source) {
|
|
5554
|
+
return computeHash(new TextEncoder().encode([
|
|
5555
|
+
source.tenant_id ?? "default",
|
|
5556
|
+
source.archive_id ?? "public",
|
|
5557
|
+
source.namespace,
|
|
5558
|
+
source.import_run_id,
|
|
5559
|
+
""
|
|
5560
|
+
].join("\0")));
|
|
5561
|
+
}
|
|
5562
|
+
function parseReceipt(value) {
|
|
5563
|
+
const parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
5564
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
5565
|
+
return parsed;
|
|
5566
|
+
}
|
|
5567
|
+
function duplicateReceipt(receipt) {
|
|
5568
|
+
const items = receipt.items.map((item) => ({ ...item, outcome: "unchanged", reason: void 0, reason_code: void 0 }));
|
|
5569
|
+
return finish(receipt.import_run_id, receipt.batch_id, false, "duplicate", items, receipt.checkpoint);
|
|
5570
|
+
}
|
|
5484
5571
|
async function insertNote(tx, input, noteId, digest2) {
|
|
5485
5572
|
const originalId = generateId();
|
|
5486
5573
|
if (input.source.archive_id) {
|
|
5487
|
-
await tx.query(
|
|
5488
|
-
`INSERT INTO archive (id, name)
|
|
5489
|
-
VALUES ($1, $2)
|
|
5490
|
-
ON CONFLICT (id) DO NOTHING`,
|
|
5491
|
-
[input.source.archive_id, input.source.archive_id]
|
|
5492
|
-
);
|
|
5574
|
+
await tx.query("INSERT INTO archive (id, name) VALUES ($1, $2) ON CONFLICT (id) DO NOTHING", [input.source.archive_id, input.source.archive_id]);
|
|
5493
5575
|
}
|
|
5494
5576
|
await tx.query(
|
|
5495
5577
|
`INSERT INTO note (id, archive_id, title, format, source, visibility)
|
|
5496
5578
|
VALUES ($1, $2, $3, $4, $5, $6)`,
|
|
5497
|
-
[
|
|
5498
|
-
noteId,
|
|
5499
|
-
input.source.archive_id ?? null,
|
|
5500
|
-
input.title ?? null,
|
|
5501
|
-
input.format ?? "markdown",
|
|
5502
|
-
`source:${input.source.namespace}`,
|
|
5503
|
-
input.visibility ?? "private"
|
|
5504
|
-
]
|
|
5579
|
+
[noteId, input.source.archive_id ?? null, input.title ?? null, input.format ?? "markdown", `source:${input.source.namespace}`, input.visibility ?? "private"]
|
|
5505
5580
|
);
|
|
5581
|
+
await tx.query("INSERT INTO note_original (id, note_id, content, content_hash) VALUES ($1, $2, $3, $4)", [originalId, noteId, input.content, digest2]);
|
|
5506
5582
|
await tx.query(
|
|
5507
|
-
`INSERT INTO
|
|
5508
|
-
VALUES ($1, $2, $3, $4)`,
|
|
5509
|
-
[
|
|
5583
|
+
`INSERT INTO note_revision (id, note_id, revision_number, type, content, ai_metadata)
|
|
5584
|
+
VALUES ($1, $2, 1, 'source-import', $3, $4::jsonb)`,
|
|
5585
|
+
[generateId(), noteId, input.content, JSON.stringify(input.metadata ?? null)]
|
|
5510
5586
|
);
|
|
5511
5587
|
await tx.query(
|
|
5512
5588
|
`INSERT INTO note_revised_current (note_id, content, ai_metadata)
|
|
@@ -5514,55 +5590,26 @@ async function insertNote(tx, input, noteId, digest2) {
|
|
|
5514
5590
|
[noteId, input.content, JSON.stringify(input.metadata ?? null)]
|
|
5515
5591
|
);
|
|
5516
5592
|
}
|
|
5517
|
-
async function updateNote(tx, input, noteId, outcome) {
|
|
5593
|
+
async function updateNote(tx, input, noteId, outcome, digest2) {
|
|
5518
5594
|
if (input.source.archive_id) {
|
|
5519
|
-
await tx.query(
|
|
5520
|
-
`INSERT INTO archive (id, name)
|
|
5521
|
-
VALUES ($1, $2)
|
|
5522
|
-
ON CONFLICT (id) DO NOTHING`,
|
|
5523
|
-
[input.source.archive_id, input.source.archive_id]
|
|
5524
|
-
);
|
|
5595
|
+
await tx.query("INSERT INTO archive (id, name) VALUES ($1, $2) ON CONFLICT (id) DO NOTHING", [input.source.archive_id, input.source.archive_id]);
|
|
5525
5596
|
}
|
|
5526
5597
|
if (outcome === "versioned") {
|
|
5527
|
-
const count2 = await tx.query(
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
`SELECT content, ai_metadata FROM note_revised_current WHERE note_id = $1`,
|
|
5533
|
-
[noteId]
|
|
5598
|
+
const count2 = await tx.query("SELECT COUNT(*) AS count FROM note_revision WHERE note_id = $1", [noteId]);
|
|
5599
|
+
await tx.query(
|
|
5600
|
+
`INSERT INTO note_revision (id, note_id, revision_number, type, content, ai_metadata)
|
|
5601
|
+
VALUES ($1, $2, $3, 'source-import', $4, $5::jsonb)`,
|
|
5602
|
+
[generateId(), noteId, Number.parseInt(count2.rows[0]?.count ?? "0", 10) + 1, input.content, JSON.stringify(input.metadata ?? null)]
|
|
5534
5603
|
);
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
await tx.query(
|
|
5538
|
-
`INSERT INTO note_revision (id, note_id, revision_number, type, content, ai_metadata)
|
|
5539
|
-
VALUES ($1, $2, $3, 'source-import', $4, $5::jsonb)`,
|
|
5540
|
-
[
|
|
5541
|
-
generateId(),
|
|
5542
|
-
noteId,
|
|
5543
|
-
nextRevision,
|
|
5544
|
-
current.rows[0].content,
|
|
5545
|
-
JSON.stringify(current.rows[0].ai_metadata ?? null)
|
|
5546
|
-
]
|
|
5547
|
-
);
|
|
5548
|
-
}
|
|
5604
|
+
} else {
|
|
5605
|
+
await tx.query("UPDATE note_original SET content = $1, content_hash = $2 WHERE note_id = $3", [input.content, digest2, noteId]);
|
|
5549
5606
|
}
|
|
5550
5607
|
await tx.query(
|
|
5551
|
-
`UPDATE note
|
|
5552
|
-
|
|
5553
|
-
WHERE id = $5`,
|
|
5554
|
-
[
|
|
5555
|
-
input.title ?? null,
|
|
5556
|
-
input.format ?? "markdown",
|
|
5557
|
-
input.visibility ?? "private",
|
|
5558
|
-
input.source.archive_id ?? null,
|
|
5559
|
-
noteId
|
|
5560
|
-
]
|
|
5608
|
+
`UPDATE note SET title = $1, format = $2, visibility = $3, archive_id = $4, updated_at = now(), deleted_at = NULL WHERE id = $5`,
|
|
5609
|
+
[input.title ?? null, input.format ?? "markdown", input.visibility ?? "private", input.source.archive_id ?? null, noteId]
|
|
5561
5610
|
);
|
|
5562
5611
|
await tx.query(
|
|
5563
|
-
`UPDATE note_revised_current
|
|
5564
|
-
SET content = $1, ai_metadata = $2::jsonb, is_user_edited = false, updated_at = now()
|
|
5565
|
-
WHERE note_id = $3`,
|
|
5612
|
+
`UPDATE note_revised_current SET content = $1, ai_metadata = $2::jsonb, is_user_edited = false, updated_at = now() WHERE note_id = $3`,
|
|
5566
5613
|
[input.content, JSON.stringify(input.metadata ?? null), noteId]
|
|
5567
5614
|
);
|
|
5568
5615
|
}
|
|
@@ -5571,184 +5618,260 @@ var SourceUpsertRepository = class {
|
|
|
5571
5618
|
this.db = db;
|
|
5572
5619
|
this.events = events;
|
|
5573
5620
|
}
|
|
5574
|
-
async
|
|
5575
|
-
const
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5621
|
+
async upsertRequest(request, scope = {}) {
|
|
5622
|
+
const tenant = scope.tenant_id ?? "default";
|
|
5623
|
+
const memory = scope.archive_id ?? null;
|
|
5624
|
+
const items = request.items.map((item) => ({
|
|
5625
|
+
source: {
|
|
5626
|
+
tenant_id: tenant,
|
|
5627
|
+
archive_id: memory,
|
|
5628
|
+
namespace: request.source_namespace,
|
|
5629
|
+
external_id: item.external_id,
|
|
5630
|
+
source_schema_version: request.source_schema_version,
|
|
5631
|
+
import_run_id: request.import_run_id,
|
|
5632
|
+
source_id: request.source_id,
|
|
5633
|
+
workspace_id: request.workspace_id,
|
|
5634
|
+
caller_stable_id: item.caller_stable_id
|
|
5635
|
+
},
|
|
5636
|
+
title: item.title,
|
|
5637
|
+
content: item.content,
|
|
5638
|
+
content_digest: item.content_digest,
|
|
5639
|
+
format: item.format,
|
|
5640
|
+
metadata: item.metadata,
|
|
5641
|
+
policy: item.policy ?? request.policy
|
|
5642
|
+
}));
|
|
5643
|
+
const invalidCommon = request.source_id !== void 0 && (request.source_id.length === 0 || request.source_id.length > 500) || request.workspace_id !== void 0 && (request.workspace_id.length === 0 || request.workspace_id.length > 500);
|
|
5644
|
+
if (invalidCommon) {
|
|
5645
|
+
const batchId = request.batch_id ?? deriveSourceBatchId(sourceRequestDigest(items, {}));
|
|
5646
|
+
const rejected = items.map((item, index) => ({
|
|
5647
|
+
index,
|
|
5648
|
+
outcome: "rejected",
|
|
5649
|
+
external_id_hash: sourceIdentityHash(item.source),
|
|
5650
|
+
content_digest: sourceContentDigest(item.content),
|
|
5651
|
+
reason_code: "invalid_batch_metadata"
|
|
5652
|
+
}));
|
|
5653
|
+
return contractResponse(finish(request.import_run_id, batchId, request.dry_run === true, "rejected", rejected, request.checkpoint));
|
|
5604
5654
|
}
|
|
5605
|
-
|
|
5606
|
-
|
|
5655
|
+
return contractResponse(await this.upsertBatch(items, {
|
|
5656
|
+
dryRun: request.dry_run,
|
|
5657
|
+
batchId: request.batch_id,
|
|
5658
|
+
checkpoint: request.checkpoint,
|
|
5659
|
+
policy: request.policy
|
|
5660
|
+
}));
|
|
5661
|
+
}
|
|
5662
|
+
async upsertBatch(items, options = {}) {
|
|
5663
|
+
const maxItems = options.maxItems ?? SOURCE_UPSERT_MAX_ITEMS;
|
|
5664
|
+
const importRunId = items[0]?.source.import_run_id ?? "";
|
|
5665
|
+
const requestDigest = sourceRequestDigest(items, options);
|
|
5666
|
+
const batchId = options.batchId ?? deriveSourceBatchId(requestDigest);
|
|
5667
|
+
const batchReason = batchId.length === 0 || batchId.length > 200 ? "invalid_batch_metadata" : JSON.stringify(options.checkpoint ?? {}).length > 65536 ? "checkpoint_too_large" : void 0;
|
|
5668
|
+
const validation = validateItems(items, maxItems, batchReason);
|
|
5669
|
+
if (validation) {
|
|
5670
|
+
return finish(importRunId, batchId, options.dryRun === true, "rejected", validation, options.checkpoint);
|
|
5607
5671
|
}
|
|
5608
5672
|
if (options.dryRun) {
|
|
5609
|
-
const preview =
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
[item.source.tenant_id ?? "default", item.source.archive_id ?? null, item.source.namespace, item.source.external_id]
|
|
5622
|
-
);
|
|
5623
|
-
if (existing.rows.length === 0) {
|
|
5624
|
-
preview.push({ index, outcome: "inserted", external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5625
|
-
} else if (existing.rows[0].content_digest === digest2) {
|
|
5626
|
-
preview.push({ index, outcome: "unchanged", note_id: existing.rows[0].note_id, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5627
|
-
} else if ((item.policy ?? "version") === "conflict") {
|
|
5628
|
-
preview.push({ index, outcome: "conflict", note_id: existing.rows[0].note_id, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5629
|
-
} else {
|
|
5630
|
-
preview.push({
|
|
5673
|
+
const preview = await previewItems(this.db, items, options.policy);
|
|
5674
|
+
return finish(importRunId, batchId, true, "preview", preview, options.checkpoint);
|
|
5675
|
+
}
|
|
5676
|
+
const response = await this.db.transaction(async (tx) => {
|
|
5677
|
+
const prior = await tx.query(
|
|
5678
|
+
`SELECT request_digest, receipt FROM source_import_batch
|
|
5679
|
+
WHERE tenant_id = $1 AND archive_id IS NOT DISTINCT FROM $2 AND namespace = $3 AND batch_id = $4 LIMIT 1`,
|
|
5680
|
+
[items[0].source.tenant_id ?? "default", items[0].source.archive_id ?? null, items[0].source.namespace, batchId]
|
|
5681
|
+
);
|
|
5682
|
+
if (prior.rows[0]) {
|
|
5683
|
+
if (prior.rows[0].request_digest !== requestDigest) {
|
|
5684
|
+
const rejected = items.map((item, index) => ({
|
|
5631
5685
|
index,
|
|
5632
|
-
outcome:
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
});
|
|
5686
|
+
outcome: "rejected",
|
|
5687
|
+
external_id_hash: sourceIdentityHash(item.source),
|
|
5688
|
+
content_digest: sourceContentDigest(item.content),
|
|
5689
|
+
reason_code: "batch_id_reused_with_different_request"
|
|
5690
|
+
}));
|
|
5691
|
+
return finish(importRunId, batchId, false, "rejected", rejected, options.checkpoint);
|
|
5692
|
+
}
|
|
5693
|
+
const receipt = parseReceipt(prior.rows[0].receipt);
|
|
5694
|
+
if (!receipt) throw new Error("Stored source upsert receipt is invalid");
|
|
5695
|
+
return duplicateReceipt(receipt);
|
|
5696
|
+
}
|
|
5697
|
+
for (const item of items) {
|
|
5698
|
+
if (!item.source.caller_stable_id) continue;
|
|
5699
|
+
const collision = await tx.query("SELECT id FROM note WHERE id = $1 LIMIT 1", [item.source.caller_stable_id]);
|
|
5700
|
+
if (collision.rows[0]) {
|
|
5701
|
+
const mapped = await findExisting(tx, item);
|
|
5702
|
+
if (mapped?.note_id === item.source.caller_stable_id) continue;
|
|
5703
|
+
const rejected = items.map((candidate, index) => ({
|
|
5704
|
+
index,
|
|
5705
|
+
outcome: "rejected",
|
|
5706
|
+
external_id_hash: sourceIdentityHash(candidate.source),
|
|
5707
|
+
content_digest: sourceContentDigest(candidate.content),
|
|
5708
|
+
reason_code: "caller_stable_id_conflict"
|
|
5709
|
+
}));
|
|
5710
|
+
return finish(importRunId, batchId, false, "rejected", rejected, options.checkpoint);
|
|
5637
5711
|
}
|
|
5638
5712
|
}
|
|
5639
|
-
|
|
5640
|
-
}
|
|
5641
|
-
await this.db.transaction(async (tx) => {
|
|
5713
|
+
const outcomes = [];
|
|
5642
5714
|
for (const [index, item] of items.entries()) {
|
|
5643
|
-
const externalIdHash =
|
|
5644
|
-
const digest2 =
|
|
5645
|
-
const existing = await tx
|
|
5646
|
-
|
|
5647
|
-
FROM source_identity
|
|
5648
|
-
WHERE tenant_id = $1
|
|
5649
|
-
AND archive_id IS NOT DISTINCT FROM $2
|
|
5650
|
-
AND namespace = $3
|
|
5651
|
-
AND external_id = $4
|
|
5652
|
-
LIMIT 1`,
|
|
5653
|
-
[item.source.tenant_id ?? "default", item.source.archive_id ?? null, item.source.namespace, item.source.external_id]
|
|
5654
|
-
);
|
|
5655
|
-
if (existing.rows.length === 0) {
|
|
5715
|
+
const externalIdHash = sourceIdentityHash(item.source);
|
|
5716
|
+
const digest2 = sourceContentDigest(item.content);
|
|
5717
|
+
const existing = await findExisting(tx, item);
|
|
5718
|
+
if (!existing) {
|
|
5656
5719
|
const noteId = item.source.caller_stable_id ?? generateId();
|
|
5657
5720
|
await insertNote(tx, item, noteId, digest2);
|
|
5658
5721
|
await tx.query(
|
|
5659
5722
|
`INSERT INTO source_identity
|
|
5660
|
-
(id, tenant_id, archive_id, namespace, external_id, external_id_hash,
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
[
|
|
5664
|
-
generateId(),
|
|
5665
|
-
item.source.tenant_id ?? "default",
|
|
5666
|
-
item.source.archive_id ?? null,
|
|
5667
|
-
item.source.namespace,
|
|
5668
|
-
item.source.external_id,
|
|
5669
|
-
externalIdHash,
|
|
5670
|
-
item.source.source_schema_version,
|
|
5671
|
-
digest2,
|
|
5672
|
-
item.source.import_run_id,
|
|
5673
|
-
item.source.caller_stable_id ?? null,
|
|
5674
|
-
noteId
|
|
5675
|
-
]
|
|
5723
|
+
(id, tenant_id, archive_id, namespace, external_id, external_id_hash, source_id, source_schema_version, content_digest, import_run_id, caller_stable_id, note_id)
|
|
5724
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`,
|
|
5725
|
+
[generateId(), item.source.tenant_id ?? "default", item.source.archive_id ?? null, item.source.namespace, item.source.external_id, externalIdHash, item.source.source_id ?? null, item.source.source_schema_version, digest2, item.source.import_run_id, item.source.caller_stable_id ?? null, noteId]
|
|
5676
5726
|
);
|
|
5677
|
-
outcomes
|
|
5727
|
+
outcomes.push({ index, outcome: "inserted", note_id: noteId, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5678
5728
|
continue;
|
|
5679
5729
|
}
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
outcomes[index] = { index, outcome: "unchanged", note_id: row.note_id, external_id_hash: externalIdHash, content_digest: digest2 };
|
|
5730
|
+
if (existing.content_digest === digest2) {
|
|
5731
|
+
outcomes.push({ index, outcome: "unchanged", note_id: existing.note_id, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5683
5732
|
continue;
|
|
5684
5733
|
}
|
|
5685
|
-
const policy = item.policy ?? "version";
|
|
5734
|
+
const policy = item.policy ?? options.policy ?? "version";
|
|
5686
5735
|
if (policy === "conflict") {
|
|
5687
|
-
outcomes
|
|
5736
|
+
outcomes.push({ index, outcome: "conflict", note_id: existing.note_id, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5688
5737
|
continue;
|
|
5689
5738
|
}
|
|
5690
5739
|
const outcome = policy === "replace" ? "replaced" : "versioned";
|
|
5691
|
-
await updateNote(tx, item,
|
|
5692
|
-
await tx.query(
|
|
5693
|
-
`UPDATE source_identity
|
|
5694
|
-
SET source_schema_version = $1, content_digest = $2, import_run_id = $3, updated_at = now()
|
|
5695
|
-
WHERE note_id = $4
|
|
5696
|
-
AND tenant_id = $5
|
|
5697
|
-
AND archive_id IS NOT DISTINCT FROM $6
|
|
5698
|
-
AND namespace = $7
|
|
5699
|
-
AND external_id = $8`,
|
|
5700
|
-
[
|
|
5701
|
-
item.source.source_schema_version,
|
|
5702
|
-
digest2,
|
|
5703
|
-
item.source.import_run_id,
|
|
5704
|
-
row.note_id,
|
|
5705
|
-
item.source.tenant_id ?? "default",
|
|
5706
|
-
item.source.archive_id ?? null,
|
|
5707
|
-
item.source.namespace,
|
|
5708
|
-
item.source.external_id
|
|
5709
|
-
]
|
|
5710
|
-
);
|
|
5711
|
-
outcomes[index] = { index, outcome, note_id: row.note_id, external_id_hash: externalIdHash, content_digest: digest2 };
|
|
5712
|
-
}
|
|
5713
|
-
if (hasMaterialChange(outcomes)) {
|
|
5740
|
+
await updateNote(tx, item, existing.note_id, outcome, digest2);
|
|
5714
5741
|
await tx.query(
|
|
5715
|
-
`
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
SET completed_at = EXCLUDED.completed_at,
|
|
5719
|
-
checkpoint = EXCLUDED.checkpoint,
|
|
5720
|
-
receipt = EXCLUDED.receipt`,
|
|
5721
|
-
[
|
|
5722
|
-
items[0].source.import_run_id,
|
|
5723
|
-
items[0].source.tenant_id ?? "default",
|
|
5724
|
-
items[0].source.archive_id ?? null,
|
|
5725
|
-
items[0].source.namespace,
|
|
5726
|
-
JSON.stringify({ item_count: items.length }),
|
|
5727
|
-
JSON.stringify({ counts: countOutcomes(outcomes) })
|
|
5728
|
-
]
|
|
5742
|
+
`UPDATE source_identity SET source_id = $1, source_schema_version = $2, content_digest = $3, import_run_id = $4, updated_at = now()
|
|
5743
|
+
WHERE note_id = $5 AND tenant_id = $6 AND archive_id IS NOT DISTINCT FROM $7 AND namespace = $8 AND external_id = $9`,
|
|
5744
|
+
[item.source.source_id ?? null, item.source.source_schema_version, digest2, item.source.import_run_id, existing.note_id, item.source.tenant_id ?? "default", item.source.archive_id ?? null, item.source.namespace, item.source.external_id]
|
|
5729
5745
|
);
|
|
5746
|
+
outcomes.push({ index, outcome, note_id: existing.note_id, external_id_hash: externalIdHash, content_digest: digest2 });
|
|
5730
5747
|
}
|
|
5748
|
+
const committed = finish(importRunId, batchId, false, "committed", outcomes, options.checkpoint);
|
|
5749
|
+
await tx.query(
|
|
5750
|
+
`INSERT INTO source_import_run (id, tenant_id, archive_id, namespace, external_run_id, source_id, source_schema_version, workspace_id, completed_at, checkpoint, receipt)
|
|
5751
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, now(), $9::jsonb, $10::jsonb)
|
|
5752
|
+
ON CONFLICT (id) DO UPDATE SET source_id = EXCLUDED.source_id, source_schema_version = EXCLUDED.source_schema_version, workspace_id = EXCLUDED.workspace_id, completed_at = EXCLUDED.completed_at, checkpoint = EXCLUDED.checkpoint, receipt = EXCLUDED.receipt`,
|
|
5753
|
+
[sourceRunRecordId(items[0].source), items[0].source.tenant_id ?? "default", items[0].source.archive_id ?? null, items[0].source.namespace, importRunId, items[0].source.source_id ?? null, items[0].source.source_schema_version, items[0].source.workspace_id ?? null, JSON.stringify(options.checkpoint ?? {}), JSON.stringify(redactedReceipt(committed))]
|
|
5754
|
+
);
|
|
5755
|
+
await tx.query(
|
|
5756
|
+
`INSERT INTO source_import_batch (id, tenant_id, archive_id, namespace, batch_id, request_digest, import_run_id, outcome, checkpoint, receipt)
|
|
5757
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, 'committed', $8::jsonb, $9::jsonb)`,
|
|
5758
|
+
[generateId(), items[0].source.tenant_id ?? "default", items[0].source.archive_id ?? null, items[0].source.namespace, batchId, requestDigest, importRunId, JSON.stringify(options.checkpoint ?? {}), JSON.stringify(redactedReceipt(committed))]
|
|
5759
|
+
);
|
|
5760
|
+
return committed;
|
|
5731
5761
|
});
|
|
5732
|
-
if (hasMaterialChange(
|
|
5733
|
-
this.events?.emit("source.upserted", { importRunId
|
|
5762
|
+
if (response.outcome === "committed" && hasMaterialChange(response.items)) {
|
|
5763
|
+
this.events?.emit("source.upserted", { importRunId, counts: response.counts });
|
|
5734
5764
|
}
|
|
5735
|
-
return
|
|
5736
|
-
}
|
|
5737
|
-
finish(importRunId, dryRun, outcomes) {
|
|
5738
|
-
return { import_run_id: importRunId, dry_run: dryRun, outcomes, counts: countOutcomes(outcomes) };
|
|
5765
|
+
return response;
|
|
5739
5766
|
}
|
|
5740
5767
|
};
|
|
5768
|
+
async function findExisting(tx, item) {
|
|
5769
|
+
const result = await tx.query(
|
|
5770
|
+
`SELECT note_id, content_digest FROM source_identity
|
|
5771
|
+
WHERE tenant_id = $1 AND archive_id IS NOT DISTINCT FROM $2 AND namespace = $3 AND external_id = $4 LIMIT 1`,
|
|
5772
|
+
[item.source.tenant_id ?? "default", item.source.archive_id ?? null, item.source.namespace, item.source.external_id]
|
|
5773
|
+
);
|
|
5774
|
+
return result.rows[0] ?? null;
|
|
5775
|
+
}
|
|
5776
|
+
async function previewItems(db, items, batchPolicy) {
|
|
5777
|
+
const preview = [];
|
|
5778
|
+
for (const [index, item] of items.entries()) {
|
|
5779
|
+
const external_id_hash = sourceIdentityHash(item.source);
|
|
5780
|
+
const content_digest = sourceContentDigest(item.content);
|
|
5781
|
+
const existing = await findExisting(db, item);
|
|
5782
|
+
if (!existing) preview.push({ index, outcome: "inserted", external_id_hash, content_digest });
|
|
5783
|
+
else if (existing.content_digest === content_digest) preview.push({ index, outcome: "unchanged", note_id: existing.note_id, external_id_hash, content_digest });
|
|
5784
|
+
else if ((item.policy ?? batchPolicy ?? "version") === "conflict") preview.push({ index, outcome: "conflict", note_id: existing.note_id, external_id_hash, content_digest });
|
|
5785
|
+
else preview.push({ index, outcome: (item.policy ?? batchPolicy) === "replace" ? "replaced" : "versioned", note_id: existing.note_id, external_id_hash, content_digest });
|
|
5786
|
+
}
|
|
5787
|
+
return preview;
|
|
5788
|
+
}
|
|
5789
|
+
function validateItems(items, maxItems, initialReason) {
|
|
5790
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5791
|
+
const stableIds = /* @__PURE__ */ new Set();
|
|
5792
|
+
const rejected = [];
|
|
5793
|
+
let batchReason = initialReason ?? (items.length === 0 || items.length > maxItems ? "batch_size_out_of_bounds" : null);
|
|
5794
|
+
for (const [index, item] of items.entries()) {
|
|
5795
|
+
const digest2 = sourceContentDigest(item.content ?? "");
|
|
5796
|
+
let reason = batchReason;
|
|
5797
|
+
try {
|
|
5798
|
+
assertSource(item.source);
|
|
5799
|
+
if (!item.content || item.content.length > 4194304) reason ??= "invalid_item";
|
|
5800
|
+
if ((item.format ?? "markdown").length > 100 || (item.title?.length ?? 0) > 2e3 || JSON.stringify(item.metadata ?? {}).length > 262144) reason ??= "invalid_item";
|
|
5801
|
+
if (item.content_digest && item.content_digest !== digest2) reason ??= "content_digest_mismatch";
|
|
5802
|
+
const identity = `${item.source.tenant_id ?? "default"}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
|
|
5803
|
+
if (seen.has(identity)) reason ??= "duplicate_external_id_in_batch";
|
|
5804
|
+
seen.add(identity);
|
|
5805
|
+
if (item.source.caller_stable_id && stableIds.has(item.source.caller_stable_id)) reason ??= "caller_stable_id_conflict";
|
|
5806
|
+
if (item.source.caller_stable_id) stableIds.add(item.source.caller_stable_id);
|
|
5807
|
+
} catch (error) {
|
|
5808
|
+
const code = error instanceof Error ? error.message : "invalid_item";
|
|
5809
|
+
reason ??= code === "invalid_batch_metadata" ? code : "invalid_item";
|
|
5810
|
+
}
|
|
5811
|
+
if (reason) {
|
|
5812
|
+
batchReason = reason;
|
|
5813
|
+
rejected.push({ index, outcome: "rejected", external_id_hash: sourceIdentityHash(item.source), content_digest: digest2, reason_code: reason });
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
if (!batchReason) return null;
|
|
5817
|
+
if (rejected.length === items.length) return rejected;
|
|
5818
|
+
return items.map((item, index) => rejected.find((result) => result.index === index) ?? {
|
|
5819
|
+
index,
|
|
5820
|
+
outcome: "rejected",
|
|
5821
|
+
external_id_hash: sourceIdentityHash(item.source),
|
|
5822
|
+
content_digest: sourceContentDigest(item.content),
|
|
5823
|
+
reason_code: batchReason
|
|
5824
|
+
});
|
|
5825
|
+
}
|
|
5826
|
+
function finish(importRunId, batchId, dryRun, outcome, items, checkpoint) {
|
|
5827
|
+
return {
|
|
5828
|
+
contract_version: SOURCE_UPSERT_CONTRACT_VERSION,
|
|
5829
|
+
import_run_id: importRunId,
|
|
5830
|
+
batch_id: batchId,
|
|
5831
|
+
dry_run: dryRun,
|
|
5832
|
+
outcome,
|
|
5833
|
+
...checkpoint ? { checkpoint } : {},
|
|
5834
|
+
items,
|
|
5835
|
+
outcomes: items,
|
|
5836
|
+
counts: countOutcomes(items)
|
|
5837
|
+
};
|
|
5838
|
+
}
|
|
5839
|
+
function redactedReceipt(receipt) {
|
|
5840
|
+
return { ...contractResponse(receipt), items: receipt.items.map(sanitizeItem) };
|
|
5841
|
+
}
|
|
5842
|
+
function contractResponse(receipt) {
|
|
5843
|
+
return {
|
|
5844
|
+
contract_version: receipt.contract_version,
|
|
5845
|
+
import_run_id: receipt.import_run_id,
|
|
5846
|
+
batch_id: receipt.batch_id,
|
|
5847
|
+
dry_run: receipt.dry_run,
|
|
5848
|
+
outcome: receipt.outcome,
|
|
5849
|
+
...receipt.checkpoint ? { checkpoint: receipt.checkpoint } : {},
|
|
5850
|
+
counts: receipt.counts,
|
|
5851
|
+
items: receipt.items
|
|
5852
|
+
};
|
|
5853
|
+
}
|
|
5854
|
+
function sanitizeItem(item) {
|
|
5855
|
+
return {
|
|
5856
|
+
index: item.index,
|
|
5857
|
+
outcome: item.outcome,
|
|
5858
|
+
...item.note_id ? { note_id: item.note_id } : {},
|
|
5859
|
+
external_id_hash: item.external_id_hash,
|
|
5860
|
+
content_digest: item.content_digest,
|
|
5861
|
+
...item.reason_code ? { reason_code: item.reason_code } : {}
|
|
5862
|
+
};
|
|
5863
|
+
}
|
|
5741
5864
|
function hasMaterialChange(outcomes) {
|
|
5742
|
-
return outcomes.some((
|
|
5865
|
+
return outcomes.some((item) => item.outcome === "inserted" || item.outcome === "versioned" || item.outcome === "replaced");
|
|
5743
5866
|
}
|
|
5744
5867
|
function countOutcomes(outcomes) {
|
|
5745
5868
|
return {
|
|
5746
|
-
inserted: outcomes.filter((
|
|
5747
|
-
unchanged: outcomes.filter((
|
|
5748
|
-
versioned: outcomes.filter((
|
|
5749
|
-
replaced: outcomes.filter((
|
|
5750
|
-
conflict: outcomes.filter((
|
|
5751
|
-
rejected: outcomes.filter((
|
|
5869
|
+
inserted: outcomes.filter((item) => item.outcome === "inserted").length,
|
|
5870
|
+
unchanged: outcomes.filter((item) => item.outcome === "unchanged").length,
|
|
5871
|
+
versioned: outcomes.filter((item) => item.outcome === "versioned").length,
|
|
5872
|
+
replaced: outcomes.filter((item) => item.outcome === "replaced").length,
|
|
5873
|
+
conflict: outcomes.filter((item) => item.outcome === "conflict").length,
|
|
5874
|
+
rejected: outcomes.filter((item) => item.outcome === "rejected").length
|
|
5752
5875
|
};
|
|
5753
5876
|
}
|
|
5754
5877
|
|
|
@@ -29407,7 +29530,7 @@ function profileOf(value) {
|
|
|
29407
29530
|
return typeof profile === "string" ? profile : void 0;
|
|
29408
29531
|
}
|
|
29409
29532
|
function validateShardManifest(value) {
|
|
29410
|
-
let
|
|
29533
|
+
let validate2;
|
|
29411
29534
|
const profile = profileOf(value);
|
|
29412
29535
|
if (profile === "core-v1") {
|
|
29413
29536
|
const version = value && typeof value === "object" && !Array.isArray(value) ? coreSchemaVersion(String(value.version ?? "")) : void 0;
|
|
@@ -29417,7 +29540,7 @@ function validateShardManifest(value) {
|
|
|
29417
29540
|
errors: ["(root) uses an unsupported canonical core-v1 schema version"]
|
|
29418
29541
|
};
|
|
29419
29542
|
}
|
|
29420
|
-
|
|
29543
|
+
validate2 = coreValidatorFor("manifest", version);
|
|
29421
29544
|
} else if (profile === "record-v1") {
|
|
29422
29545
|
const version = value && typeof value === "object" && !Array.isArray(value) ? recordSchemaVersion(String(value.version ?? "")) : void 0;
|
|
29423
29546
|
if (!version) {
|
|
@@ -29426,7 +29549,7 @@ function validateShardManifest(value) {
|
|
|
29426
29549
|
errors: ["(root) uses an unsupported canonical record-v1 schema version"]
|
|
29427
29550
|
};
|
|
29428
29551
|
}
|
|
29429
|
-
|
|
29552
|
+
validate2 = recordValidatorFor("manifest", version);
|
|
29430
29553
|
} else if (profile === "full-v1") {
|
|
29431
29554
|
const version = value && typeof value === "object" && !Array.isArray(value) ? fullSchemaVersion(String(value.version ?? "")) : void 0;
|
|
29432
29555
|
if (!version) {
|
|
@@ -29435,12 +29558,12 @@ function validateShardManifest(value) {
|
|
|
29435
29558
|
errors: ["(root) uses an unsupported canonical full-v1 schema version"]
|
|
29436
29559
|
};
|
|
29437
29560
|
}
|
|
29438
|
-
|
|
29561
|
+
validate2 = fullValidatorFor("manifest", version);
|
|
29439
29562
|
} else {
|
|
29440
|
-
|
|
29563
|
+
validate2 = legacyValidatorFor("manifest");
|
|
29441
29564
|
}
|
|
29442
|
-
const valid =
|
|
29443
|
-
return { valid, errors: formatErrors(
|
|
29565
|
+
const valid = validate2(value);
|
|
29566
|
+
return { valid, errors: formatErrors(validate2.errors) };
|
|
29444
29567
|
}
|
|
29445
29568
|
function parseJsonArray(bytes, path) {
|
|
29446
29569
|
if (!bytes) return { records: [], errors: [] };
|
|
@@ -29883,9 +30006,9 @@ async function validateFullV1ShardArchive(input) {
|
|
|
29883
30006
|
return { valid: errors.length === 0, errors };
|
|
29884
30007
|
}
|
|
29885
30008
|
function validateShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
29886
|
-
let
|
|
30009
|
+
let validate2;
|
|
29887
30010
|
if (profile === "core-v1" && component in CORE_V1_COMPONENT_FILES) {
|
|
29888
|
-
|
|
30011
|
+
validate2 = coreValidatorFor(component, version);
|
|
29889
30012
|
} else if (profile === "record-v1" && component in RECORD_V1_COMPONENT_FILES) {
|
|
29890
30013
|
const canonicalVersion = recordSchemaVersion(version);
|
|
29891
30014
|
if (!canonicalVersion) {
|
|
@@ -29894,7 +30017,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
29894
30017
|
errors: [`(root) uses an unsupported canonical record-v1 schema version ${version}`]
|
|
29895
30018
|
};
|
|
29896
30019
|
}
|
|
29897
|
-
|
|
30020
|
+
validate2 = recordValidatorFor(component, canonicalVersion);
|
|
29898
30021
|
} else if (profile === "full-v1" && component in FULL_V1_COMPONENT_FILES) {
|
|
29899
30022
|
const canonicalVersion = fullSchemaVersion(version);
|
|
29900
30023
|
if (!canonicalVersion) {
|
|
@@ -29903,7 +30026,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
29903
30026
|
errors: [`(root) uses an unsupported canonical full-v1 schema version ${version}`]
|
|
29904
30027
|
};
|
|
29905
30028
|
}
|
|
29906
|
-
|
|
30029
|
+
validate2 = fullValidatorFor(component, canonicalVersion);
|
|
29907
30030
|
} else {
|
|
29908
30031
|
const legacyDef = LEGACY_COMPONENT_SCHEMA_DEFS[component];
|
|
29909
30032
|
if (!legacyDef) {
|
|
@@ -29912,10 +30035,10 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
29912
30035
|
errors: [`(root) component '${component}' requires an explicit full-v1 profile`]
|
|
29913
30036
|
};
|
|
29914
30037
|
}
|
|
29915
|
-
|
|
30038
|
+
validate2 = legacyValidatorFor(legacyDef);
|
|
29916
30039
|
}
|
|
29917
|
-
const valid =
|
|
29918
|
-
return { valid, errors: formatErrors(
|
|
30040
|
+
const valid = validate2(value);
|
|
30041
|
+
return { valid, errors: formatErrors(validate2.errors) };
|
|
29919
30042
|
}
|
|
29920
30043
|
function assertShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
29921
30044
|
const result = validateShardComponentRecord(component, value, profile, version);
|
|
@@ -36228,7 +36351,7 @@ function getProjectedRecordValidator() {
|
|
|
36228
36351
|
return projectedRecordValidator;
|
|
36229
36352
|
}
|
|
36230
36353
|
function validateAiwgFortemiIndexExportSchema(value) {
|
|
36231
|
-
const
|
|
36354
|
+
const validate2 = getExportValidator();
|
|
36232
36355
|
const schemaValue = value && typeof value === "object" && Array.isArray(value.items) ? {
|
|
36233
36356
|
...value,
|
|
36234
36357
|
items: value.items.map((item) => {
|
|
@@ -36238,13 +36361,13 @@ function validateAiwgFortemiIndexExportSchema(value) {
|
|
|
36238
36361
|
return schemaRecord;
|
|
36239
36362
|
})
|
|
36240
36363
|
} : value;
|
|
36241
|
-
const valid =
|
|
36242
|
-
return { valid, errors: formatErrors2(
|
|
36364
|
+
const valid = validate2(schemaValue);
|
|
36365
|
+
return { valid, errors: formatErrors2(validate2.errors) };
|
|
36243
36366
|
}
|
|
36244
36367
|
function validateAiwgFortemiProjectedRecordSchema(value) {
|
|
36245
|
-
const
|
|
36246
|
-
const valid =
|
|
36247
|
-
return { valid, errors: formatErrors2(
|
|
36368
|
+
const validate2 = getProjectedRecordValidator();
|
|
36369
|
+
const valid = validate2(value);
|
|
36370
|
+
return { valid, errors: formatErrors2(validate2.errors) };
|
|
36248
36371
|
}
|
|
36249
36372
|
var encoder5 = new TextEncoder();
|
|
36250
36373
|
var UUID_NAMESPACE = "7ab5d1f8-29d2-5e35-9e2f-3a45de171a9e";
|
|
@@ -37235,6 +37358,7 @@ var RECORD_COLLECTIONS = [
|
|
|
37235
37358
|
"note",
|
|
37236
37359
|
"note_original",
|
|
37237
37360
|
"note_revised_current",
|
|
37361
|
+
"note_revision",
|
|
37238
37362
|
"note_tag",
|
|
37239
37363
|
"link",
|
|
37240
37364
|
"collection",
|
|
@@ -37244,6 +37368,7 @@ var RECORD_COLLECTIONS = [
|
|
|
37244
37368
|
"shard_manifest",
|
|
37245
37369
|
"source_identity",
|
|
37246
37370
|
"source_import_run",
|
|
37371
|
+
"source_import_batch",
|
|
37247
37372
|
"deletion_receipt"
|
|
37248
37373
|
];
|
|
37249
37374
|
var RECORD_STORE_CAPABILITIES = {
|
|
@@ -37366,10 +37491,10 @@ var MemoryRecordStore = class {
|
|
|
37366
37491
|
};
|
|
37367
37492
|
|
|
37368
37493
|
// src/records/idb-record-store.ts
|
|
37369
|
-
var DB_VERSION =
|
|
37494
|
+
var DB_VERSION = 3;
|
|
37370
37495
|
var JOURNAL_STORE = "journal";
|
|
37371
37496
|
var META_STORE = "meta";
|
|
37372
|
-
var RECORD_SCHEMA_VERSION =
|
|
37497
|
+
var RECORD_SCHEMA_VERSION = 3;
|
|
37373
37498
|
function requestToPromise(request) {
|
|
37374
37499
|
return new Promise((resolve, reject) => {
|
|
37375
37500
|
request.onsuccess = () => resolve(request.result);
|
|
@@ -37926,10 +38051,11 @@ function collectionsParentFirst(collections) {
|
|
|
37926
38051
|
return ordered;
|
|
37927
38052
|
}
|
|
37928
38053
|
async function projectNotes(db, store) {
|
|
37929
|
-
const [noteRows, originals, revised, tags, links, collections, memberships] = await Promise.all([
|
|
38054
|
+
const [noteRows, originals, revised, revisions, tags, links, collections, memberships] = await Promise.all([
|
|
37930
38055
|
store.list("note"),
|
|
37931
38056
|
store.list("note_original"),
|
|
37932
38057
|
store.list("note_revised_current"),
|
|
38058
|
+
store.list("note_revision"),
|
|
37933
38059
|
store.list("note_tag"),
|
|
37934
38060
|
store.list("link"),
|
|
37935
38061
|
store.list("collection"),
|
|
@@ -38026,6 +38152,28 @@ async function projectNotes(db, store) {
|
|
|
38026
38152
|
]
|
|
38027
38153
|
);
|
|
38028
38154
|
}
|
|
38155
|
+
for (const r of revisions) {
|
|
38156
|
+
await db.query(
|
|
38157
|
+
`INSERT INTO note_revision (id, note_id, revision_number, type, content, ai_metadata, model, created_at)
|
|
38158
|
+
VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8)
|
|
38159
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
38160
|
+
revision_number = EXCLUDED.revision_number,
|
|
38161
|
+
type = EXCLUDED.type,
|
|
38162
|
+
content = EXCLUDED.content,
|
|
38163
|
+
ai_metadata = EXCLUDED.ai_metadata,
|
|
38164
|
+
model = EXCLUDED.model`,
|
|
38165
|
+
[
|
|
38166
|
+
r.id,
|
|
38167
|
+
r.note_id,
|
|
38168
|
+
r.revision_number,
|
|
38169
|
+
r.type,
|
|
38170
|
+
r.content,
|
|
38171
|
+
r.ai_metadata == null ? null : JSON.stringify(r.ai_metadata),
|
|
38172
|
+
r.model,
|
|
38173
|
+
r.created_at
|
|
38174
|
+
]
|
|
38175
|
+
);
|
|
38176
|
+
}
|
|
38029
38177
|
for (const t of tags) {
|
|
38030
38178
|
await db.query(
|
|
38031
38179
|
`INSERT INTO note_tag (id, note_id, tag, created_at)
|
|
@@ -38062,6 +38210,7 @@ async function projectNotes(db, store) {
|
|
|
38062
38210
|
);
|
|
38063
38211
|
return {
|
|
38064
38212
|
notes: noteRows.length,
|
|
38213
|
+
revisions: revisions.length,
|
|
38065
38214
|
tags: tags.length,
|
|
38066
38215
|
links: links.length,
|
|
38067
38216
|
collections: collections.length,
|
|
@@ -39296,177 +39445,283 @@ async function importShardToRecords(store, data, options) {
|
|
|
39296
39445
|
function now() {
|
|
39297
39446
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
39298
39447
|
}
|
|
39299
|
-
function contentDigest2(content) {
|
|
39300
|
-
return computeHash(new TextEncoder().encode(content));
|
|
39301
|
-
}
|
|
39302
|
-
function sourceHash2(source) {
|
|
39303
|
-
return computeHash(new TextEncoder().encode([
|
|
39304
|
-
source.tenant_id ?? "default",
|
|
39305
|
-
source.archive_id ?? "",
|
|
39306
|
-
source.namespace,
|
|
39307
|
-
source.external_id
|
|
39308
|
-
].join("\0")));
|
|
39309
|
-
}
|
|
39310
39448
|
function countOutcomes2(outcomes) {
|
|
39311
39449
|
return {
|
|
39312
|
-
inserted: outcomes.filter((
|
|
39313
|
-
unchanged: outcomes.filter((
|
|
39314
|
-
versioned: outcomes.filter((
|
|
39315
|
-
replaced: outcomes.filter((
|
|
39316
|
-
conflict: outcomes.filter((
|
|
39317
|
-
rejected: outcomes.filter((
|
|
39450
|
+
inserted: outcomes.filter((item) => item.outcome === "inserted").length,
|
|
39451
|
+
unchanged: outcomes.filter((item) => item.outcome === "unchanged").length,
|
|
39452
|
+
versioned: outcomes.filter((item) => item.outcome === "versioned").length,
|
|
39453
|
+
replaced: outcomes.filter((item) => item.outcome === "replaced").length,
|
|
39454
|
+
conflict: outcomes.filter((item) => item.outcome === "conflict").length,
|
|
39455
|
+
rejected: outcomes.filter((item) => item.outcome === "rejected").length
|
|
39456
|
+
};
|
|
39457
|
+
}
|
|
39458
|
+
function finish2(importRunId, batchId, dryRun, outcome, items, checkpoint) {
|
|
39459
|
+
return {
|
|
39460
|
+
contract_version: SOURCE_UPSERT_CONTRACT_VERSION,
|
|
39461
|
+
import_run_id: importRunId,
|
|
39462
|
+
batch_id: batchId,
|
|
39463
|
+
dry_run: dryRun,
|
|
39464
|
+
outcome,
|
|
39465
|
+
...checkpoint ? { checkpoint } : {},
|
|
39466
|
+
items,
|
|
39467
|
+
outcomes: items,
|
|
39468
|
+
counts: countOutcomes2(items)
|
|
39318
39469
|
};
|
|
39319
39470
|
}
|
|
39320
39471
|
async function findSource(store, source) {
|
|
39321
39472
|
const identities = await store.list("source_identity");
|
|
39322
39473
|
return identities.find((identity) => identity.tenant_id === (source.tenant_id ?? "default") && identity.archive_id === (source.archive_id ?? null) && identity.namespace === source.namespace && identity.external_id === source.external_id) ?? null;
|
|
39323
39474
|
}
|
|
39475
|
+
async function upsertRecordStoreRequest(store, request, scope = {}) {
|
|
39476
|
+
const items = request.items.map((item) => ({
|
|
39477
|
+
source: {
|
|
39478
|
+
tenant_id: scope.tenant_id ?? "default",
|
|
39479
|
+
archive_id: scope.archive_id ?? null,
|
|
39480
|
+
namespace: request.source_namespace,
|
|
39481
|
+
external_id: item.external_id,
|
|
39482
|
+
source_schema_version: request.source_schema_version,
|
|
39483
|
+
import_run_id: request.import_run_id,
|
|
39484
|
+
source_id: request.source_id,
|
|
39485
|
+
workspace_id: request.workspace_id,
|
|
39486
|
+
caller_stable_id: item.caller_stable_id
|
|
39487
|
+
},
|
|
39488
|
+
title: item.title,
|
|
39489
|
+
content: item.content,
|
|
39490
|
+
content_digest: item.content_digest,
|
|
39491
|
+
format: item.format,
|
|
39492
|
+
metadata: item.metadata,
|
|
39493
|
+
policy: item.policy ?? request.policy
|
|
39494
|
+
}));
|
|
39495
|
+
const result = await upsertRecordStoreSources(store, items, {
|
|
39496
|
+
dryRun: request.dry_run,
|
|
39497
|
+
batchId: request.batch_id,
|
|
39498
|
+
checkpoint: request.checkpoint,
|
|
39499
|
+
policy: request.policy
|
|
39500
|
+
});
|
|
39501
|
+
return {
|
|
39502
|
+
contract_version: result.contract_version,
|
|
39503
|
+
import_run_id: result.import_run_id,
|
|
39504
|
+
batch_id: result.batch_id,
|
|
39505
|
+
dry_run: result.dry_run,
|
|
39506
|
+
outcome: result.outcome,
|
|
39507
|
+
...result.checkpoint ? { checkpoint: result.checkpoint } : {},
|
|
39508
|
+
counts: result.counts,
|
|
39509
|
+
items: result.items
|
|
39510
|
+
};
|
|
39511
|
+
}
|
|
39324
39512
|
async function upsertRecordStoreSources(store, items, options = {}) {
|
|
39325
|
-
const maxItems = options.maxItems ?? 500;
|
|
39326
|
-
if (items.length > maxItems) throw new Error(`Source upsert batch exceeds the ${maxItems} item bound`);
|
|
39327
39513
|
if (!store.applyBatch) throw new Error("RecordStore source upsert requires atomic applyBatch() support");
|
|
39328
|
-
|
|
39329
|
-
|
|
39330
|
-
|
|
39331
|
-
|
|
39332
|
-
|
|
39333
|
-
|
|
39334
|
-
|
|
39514
|
+
const importRunId = items[0]?.source.import_run_id ?? "";
|
|
39515
|
+
const requestDigest = sourceRequestDigest(items, options);
|
|
39516
|
+
const batchId = options.batchId ?? deriveSourceBatchId(requestDigest);
|
|
39517
|
+
const batchReason = batchId.length === 0 || batchId.length > 200 ? "invalid_batch_metadata" : JSON.stringify(options.checkpoint ?? {}).length > 65536 ? "checkpoint_too_large" : void 0;
|
|
39518
|
+
const validation = validate(items, options.maxItems ?? 500, batchReason);
|
|
39519
|
+
if (validation) return finish2(importRunId, batchId, options.dryRun === true, "rejected", validation, options.checkpoint);
|
|
39520
|
+
const batches = await store.list("source_import_batch");
|
|
39521
|
+
const prior = batches.find((batch2) => batch2.tenant_id === (items[0].source.tenant_id ?? "default") && batch2.archive_id === (items[0].source.archive_id ?? null) && batch2.namespace === items[0].source.namespace && batch2.batch_id === batchId);
|
|
39522
|
+
if (prior) {
|
|
39523
|
+
if (prior.request_digest !== requestDigest) {
|
|
39524
|
+
const rejected = items.map((item, index) => ({
|
|
39525
|
+
index,
|
|
39526
|
+
outcome: "rejected",
|
|
39527
|
+
external_id_hash: sourceIdentityHash(item.source),
|
|
39528
|
+
content_digest: sourceContentDigest(item.content),
|
|
39529
|
+
reason_code: "batch_id_reused_with_different_request"
|
|
39530
|
+
}));
|
|
39531
|
+
return finish2(importRunId, batchId, false, "rejected", rejected, options.checkpoint);
|
|
39532
|
+
}
|
|
39533
|
+
const receipt = prior.receipt;
|
|
39534
|
+
const unchanged = receipt.items.map((item) => ({ ...item, outcome: "unchanged", reason_code: void 0, reason: void 0 }));
|
|
39535
|
+
return finish2(importRunId, batchId, false, "duplicate", unchanged, receipt.checkpoint);
|
|
39335
39536
|
}
|
|
39336
39537
|
const outcomes = [];
|
|
39337
39538
|
const mutations = [];
|
|
39338
39539
|
const stamp = now();
|
|
39339
39540
|
for (const [index, item] of items.entries()) {
|
|
39340
|
-
const external_id_hash =
|
|
39341
|
-
const content_digest =
|
|
39541
|
+
const external_id_hash = sourceIdentityHash(item.source);
|
|
39542
|
+
const content_digest = sourceContentDigest(item.content);
|
|
39342
39543
|
const existing = await findSource(store, item.source);
|
|
39343
39544
|
if (!existing) {
|
|
39344
39545
|
const noteId = item.source.caller_stable_id ?? generateId();
|
|
39345
|
-
|
|
39346
|
-
|
|
39347
|
-
|
|
39348
|
-
|
|
39349
|
-
|
|
39350
|
-
|
|
39351
|
-
|
|
39352
|
-
|
|
39353
|
-
|
|
39354
|
-
revision_mode: "standard",
|
|
39355
|
-
is_starred: false,
|
|
39356
|
-
is_pinned: false,
|
|
39357
|
-
is_archived: false,
|
|
39358
|
-
created_at: stamp,
|
|
39359
|
-
updated_at: stamp,
|
|
39360
|
-
deleted_at: null
|
|
39361
|
-
};
|
|
39362
|
-
const original = {
|
|
39363
|
-
id: generateId(),
|
|
39364
|
-
note_id: noteId,
|
|
39365
|
-
content: item.content,
|
|
39366
|
-
content_hash: content_digest,
|
|
39367
|
-
created_at: stamp
|
|
39368
|
-
};
|
|
39369
|
-
const current2 = {
|
|
39370
|
-
id: noteId,
|
|
39371
|
-
content: item.content,
|
|
39372
|
-
ai_metadata: item.metadata ?? null,
|
|
39373
|
-
generation_count: 0,
|
|
39374
|
-
model: null,
|
|
39375
|
-
is_user_edited: false,
|
|
39376
|
-
updated_at: stamp
|
|
39377
|
-
};
|
|
39378
|
-
const identity = {
|
|
39379
|
-
id: generateId(),
|
|
39380
|
-
tenant_id: item.source.tenant_id ?? "default",
|
|
39381
|
-
archive_id: item.source.archive_id ?? null,
|
|
39382
|
-
namespace: item.source.namespace,
|
|
39383
|
-
external_id: item.source.external_id,
|
|
39384
|
-
external_id_hash,
|
|
39385
|
-
source_schema_version: item.source.source_schema_version,
|
|
39386
|
-
content_digest,
|
|
39387
|
-
import_run_id: item.source.import_run_id,
|
|
39388
|
-
caller_stable_id: item.source.caller_stable_id ?? null,
|
|
39389
|
-
note_id: noteId,
|
|
39390
|
-
created_at: stamp,
|
|
39391
|
-
updated_at: stamp
|
|
39392
|
-
};
|
|
39393
|
-
mutations.push(
|
|
39394
|
-
{ op: "put", collection: "note", record: note2 },
|
|
39395
|
-
{ op: "put", collection: "note_original", record: original },
|
|
39396
|
-
{ op: "put", collection: "note_revised_current", record: current2 },
|
|
39397
|
-
{ op: "put", collection: "source_identity", record: identity }
|
|
39398
|
-
);
|
|
39546
|
+
if (await store.get("note", noteId)) {
|
|
39547
|
+
const rejected = items.map((candidate, candidateIndex) => ({
|
|
39548
|
+
index: candidateIndex,
|
|
39549
|
+
outcome: "rejected",
|
|
39550
|
+
external_id_hash: sourceIdentityHash(candidate.source),
|
|
39551
|
+
content_digest: sourceContentDigest(candidate.content),
|
|
39552
|
+
reason_code: "caller_stable_id_conflict"
|
|
39553
|
+
}));
|
|
39554
|
+
return finish2(importRunId, batchId, false, "rejected", rejected, options.checkpoint);
|
|
39399
39555
|
}
|
|
39556
|
+
outcomes.push({ index, outcome: "inserted", note_id: noteId, external_id_hash, content_digest });
|
|
39557
|
+
if (!options.dryRun) addInsertMutations(mutations, item, noteId, content_digest, external_id_hash, stamp);
|
|
39400
39558
|
continue;
|
|
39401
39559
|
}
|
|
39402
39560
|
if (existing.content_digest === content_digest) {
|
|
39403
39561
|
outcomes.push({ index, outcome: "unchanged", note_id: existing.note_id, external_id_hash, content_digest });
|
|
39404
39562
|
continue;
|
|
39405
39563
|
}
|
|
39406
|
-
const policy = item.policy ?? "version";
|
|
39564
|
+
const policy = item.policy ?? options.policy ?? "version";
|
|
39407
39565
|
if (policy === "conflict") {
|
|
39408
39566
|
outcomes.push({ index, outcome: "conflict", note_id: existing.note_id, external_id_hash, content_digest });
|
|
39409
39567
|
continue;
|
|
39410
39568
|
}
|
|
39411
39569
|
const note = await store.get("note", existing.note_id);
|
|
39412
39570
|
const current = await store.get("note_revised_current", existing.note_id);
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39571
|
+
const originals = await store.list("note_original");
|
|
39572
|
+
const original = originals.find((candidate) => candidate.note_id === existing.note_id);
|
|
39573
|
+
if (!note || !current || !original) {
|
|
39574
|
+
const rejected = items.map((candidate, candidateIndex) => ({
|
|
39575
|
+
index: candidateIndex,
|
|
39576
|
+
outcome: "rejected",
|
|
39577
|
+
note_id: candidateIndex === index ? existing.note_id : void 0,
|
|
39578
|
+
external_id_hash: sourceIdentityHash(candidate.source),
|
|
39579
|
+
content_digest: sourceContentDigest(candidate.content),
|
|
39580
|
+
reason_code: "invalid_item"
|
|
39581
|
+
}));
|
|
39582
|
+
return finish2(importRunId, batchId, false, "rejected", rejected, options.checkpoint);
|
|
39416
39583
|
}
|
|
39417
39584
|
const outcome = policy === "replace" ? "replaced" : "versioned";
|
|
39418
39585
|
outcomes.push({ index, outcome, note_id: existing.note_id, external_id_hash, content_digest });
|
|
39419
39586
|
if (!options.dryRun) {
|
|
39420
|
-
|
|
39421
|
-
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
|
|
39425
|
-
|
|
39426
|
-
|
|
39427
|
-
|
|
39428
|
-
|
|
39429
|
-
|
|
39430
|
-
|
|
39431
|
-
|
|
39432
|
-
|
|
39433
|
-
|
|
39434
|
-
|
|
39435
|
-
|
|
39436
|
-
|
|
39437
|
-
|
|
39438
|
-
|
|
39439
|
-
|
|
39440
|
-
|
|
39441
|
-
|
|
39442
|
-
|
|
39443
|
-
|
|
39444
|
-
|
|
39445
|
-
|
|
39446
|
-
|
|
39447
|
-
|
|
39448
|
-
|
|
39449
|
-
|
|
39450
|
-
|
|
39451
|
-
|
|
39452
|
-
|
|
39453
|
-
|
|
39454
|
-
|
|
39455
|
-
|
|
39456
|
-
|
|
39587
|
+
const revisionNumber = outcome === "versioned" ? (await store.list("note_revision")).filter((row) => row.note_id === existing.note_id).length + 1 : void 0;
|
|
39588
|
+
addUpdateMutations(mutations, item, existing, note, current, original, outcome, content_digest, stamp, revisionNumber);
|
|
39589
|
+
}
|
|
39590
|
+
}
|
|
39591
|
+
if (options.dryRun) return finish2(importRunId, batchId, true, "preview", outcomes, options.checkpoint);
|
|
39592
|
+
const committed = finish2(importRunId, batchId, false, "committed", outcomes, options.checkpoint);
|
|
39593
|
+
const contractReceipt = {
|
|
39594
|
+
contract_version: committed.contract_version,
|
|
39595
|
+
import_run_id: committed.import_run_id,
|
|
39596
|
+
batch_id: committed.batch_id,
|
|
39597
|
+
dry_run: committed.dry_run,
|
|
39598
|
+
outcome: committed.outcome,
|
|
39599
|
+
...committed.checkpoint ? { checkpoint: committed.checkpoint } : {},
|
|
39600
|
+
counts: committed.counts,
|
|
39601
|
+
items: committed.items
|
|
39602
|
+
};
|
|
39603
|
+
const run = {
|
|
39604
|
+
id: sourceRunRecordId(items[0].source),
|
|
39605
|
+
external_run_id: importRunId,
|
|
39606
|
+
source_id: items[0].source.source_id ?? null,
|
|
39607
|
+
source_schema_version: items[0].source.source_schema_version,
|
|
39608
|
+
workspace_id: items[0].source.workspace_id ?? null,
|
|
39609
|
+
tenant_id: items[0].source.tenant_id ?? "default",
|
|
39610
|
+
archive_id: items[0].source.archive_id ?? null,
|
|
39611
|
+
namespace: items[0].source.namespace,
|
|
39612
|
+
started_at: stamp,
|
|
39613
|
+
completed_at: stamp,
|
|
39614
|
+
checkpoint: options.checkpoint ?? {},
|
|
39615
|
+
receipt: contractReceipt
|
|
39616
|
+
};
|
|
39617
|
+
const batch = {
|
|
39618
|
+
id: generateId(),
|
|
39619
|
+
tenant_id: items[0].source.tenant_id ?? "default",
|
|
39620
|
+
archive_id: items[0].source.archive_id ?? null,
|
|
39621
|
+
namespace: items[0].source.namespace,
|
|
39622
|
+
batch_id: batchId,
|
|
39623
|
+
request_digest: requestDigest,
|
|
39624
|
+
import_run_id: importRunId,
|
|
39625
|
+
outcome: "committed",
|
|
39626
|
+
checkpoint: options.checkpoint ?? {},
|
|
39627
|
+
receipt: contractReceipt,
|
|
39628
|
+
created_at: stamp
|
|
39629
|
+
};
|
|
39630
|
+
mutations.push(
|
|
39631
|
+
{ op: "put", collection: "source_import_run", record: run },
|
|
39632
|
+
{ op: "put", collection: "source_import_batch", record: batch }
|
|
39633
|
+
);
|
|
39634
|
+
await store.applyBatch(mutations);
|
|
39635
|
+
return committed;
|
|
39636
|
+
}
|
|
39637
|
+
function addInsertMutations(mutations, item, noteId, contentDigest, externalIdHash, stamp) {
|
|
39638
|
+
const note = {
|
|
39639
|
+
id: noteId,
|
|
39640
|
+
archive_id: item.source.archive_id ?? null,
|
|
39641
|
+
title: item.title ?? null,
|
|
39642
|
+
format: item.format ?? "markdown",
|
|
39643
|
+
source: `source:${item.source.namespace}`,
|
|
39644
|
+
visibility: item.visibility ?? "private",
|
|
39645
|
+
revision_mode: "standard",
|
|
39646
|
+
is_starred: false,
|
|
39647
|
+
is_pinned: false,
|
|
39648
|
+
is_archived: false,
|
|
39649
|
+
created_at: stamp,
|
|
39650
|
+
updated_at: stamp,
|
|
39651
|
+
deleted_at: null
|
|
39652
|
+
};
|
|
39653
|
+
const original = { id: generateId(), note_id: noteId, content: item.content, content_hash: contentDigest, created_at: stamp };
|
|
39654
|
+
const current = { id: noteId, content: item.content, ai_metadata: item.metadata ?? null, generation_count: 0, model: null, is_user_edited: false, updated_at: stamp };
|
|
39655
|
+
const revision = { id: generateId(), note_id: noteId, revision_number: 1, type: "source-import", content: item.content, ai_metadata: item.metadata ?? null, model: null, created_at: stamp };
|
|
39656
|
+
const identity = {
|
|
39657
|
+
id: generateId(),
|
|
39658
|
+
tenant_id: item.source.tenant_id ?? "default",
|
|
39659
|
+
archive_id: item.source.archive_id ?? null,
|
|
39660
|
+
namespace: item.source.namespace,
|
|
39661
|
+
external_id: item.source.external_id,
|
|
39662
|
+
external_id_hash: externalIdHash,
|
|
39663
|
+
source_id: item.source.source_id ?? null,
|
|
39664
|
+
source_schema_version: item.source.source_schema_version,
|
|
39665
|
+
content_digest: contentDigest,
|
|
39666
|
+
import_run_id: item.source.import_run_id,
|
|
39667
|
+
caller_stable_id: item.source.caller_stable_id ?? null,
|
|
39668
|
+
note_id: noteId,
|
|
39669
|
+
created_at: stamp,
|
|
39670
|
+
updated_at: stamp
|
|
39671
|
+
};
|
|
39672
|
+
mutations.push(
|
|
39673
|
+
{ op: "put", collection: "note", record: note },
|
|
39674
|
+
{ op: "put", collection: "note_original", record: original },
|
|
39675
|
+
{ op: "put", collection: "note_revised_current", record: current },
|
|
39676
|
+
{ op: "put", collection: "note_revision", record: revision },
|
|
39677
|
+
{ op: "put", collection: "source_identity", record: identity }
|
|
39678
|
+
);
|
|
39679
|
+
}
|
|
39680
|
+
function addUpdateMutations(mutations, item, identity, note, current, original, outcome, contentDigest, stamp, revisionNumber) {
|
|
39681
|
+
mutations.push(
|
|
39682
|
+
{ op: "put", collection: "note", record: { ...note, title: item.title ?? null, archive_id: item.source.archive_id ?? null, format: item.format ?? "markdown", visibility: item.visibility ?? "private", deleted_at: null, updated_at: stamp } },
|
|
39683
|
+
{ op: "put", collection: "note_revised_current", record: { ...current, content: item.content, ai_metadata: item.metadata ?? null, is_user_edited: false, updated_at: stamp } },
|
|
39684
|
+
{ op: "put", collection: "source_identity", record: { ...identity, source_id: item.source.source_id ?? null, source_schema_version: item.source.source_schema_version, content_digest: contentDigest, import_run_id: item.source.import_run_id, updated_at: stamp } }
|
|
39685
|
+
);
|
|
39686
|
+
if (outcome === "replaced") {
|
|
39687
|
+
mutations.push({ op: "put", collection: "note_original", record: { ...original, content: item.content, content_hash: contentDigest } });
|
|
39688
|
+
} else {
|
|
39689
|
+
const revision = {
|
|
39690
|
+
id: generateId(),
|
|
39691
|
+
note_id: identity.note_id,
|
|
39692
|
+
revision_number: revisionNumber ?? 1,
|
|
39693
|
+
type: "source-import",
|
|
39694
|
+
content: item.content,
|
|
39695
|
+
ai_metadata: item.metadata ?? null,
|
|
39696
|
+
model: null,
|
|
39697
|
+
created_at: stamp
|
|
39457
39698
|
};
|
|
39458
|
-
mutations.push({ op: "put", collection: "
|
|
39459
|
-
await store.applyBatch(mutations);
|
|
39699
|
+
mutations.push({ op: "put", collection: "note_revision", record: revision });
|
|
39460
39700
|
}
|
|
39461
|
-
return {
|
|
39462
|
-
import_run_id: items[0].source.import_run_id,
|
|
39463
|
-
dry_run: options.dryRun === true,
|
|
39464
|
-
outcomes,
|
|
39465
|
-
counts: countOutcomes2(outcomes)
|
|
39466
|
-
};
|
|
39467
39701
|
}
|
|
39468
|
-
function
|
|
39469
|
-
|
|
39702
|
+
function validate(items, maxItems, initialReason) {
|
|
39703
|
+
let reason = initialReason ?? (items.length === 0 || items.length > maxItems ? "batch_size_out_of_bounds" : null);
|
|
39704
|
+
const seen = /* @__PURE__ */ new Set();
|
|
39705
|
+
const stableIds = /* @__PURE__ */ new Set();
|
|
39706
|
+
for (const item of items) {
|
|
39707
|
+
if (!item.source.tenant_id || !item.source.namespace || !item.source.external_id || !item.source.source_schema_version || !item.source.import_run_id || !item.content) reason ??= "invalid_item";
|
|
39708
|
+
if ((item.source.source_id?.length ?? 0) > 500 || item.source.source_id === "" || (item.source.workspace_id?.length ?? 0) > 500 || item.source.workspace_id === "") reason ??= "invalid_batch_metadata";
|
|
39709
|
+
if ((item.format ?? "markdown").length > 100 || (item.title?.length ?? 0) > 2e3 || JSON.stringify(item.metadata ?? {}).length > 262144) reason ??= "invalid_item";
|
|
39710
|
+
if (item.content_digest && item.content_digest !== sourceContentDigest(item.content)) reason ??= "content_digest_mismatch";
|
|
39711
|
+
const key = `${item.source.tenant_id}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
|
|
39712
|
+
if (seen.has(key)) reason ??= "duplicate_external_id_in_batch";
|
|
39713
|
+
seen.add(key);
|
|
39714
|
+
if (item.source.caller_stable_id && stableIds.has(item.source.caller_stable_id)) reason ??= "caller_stable_id_conflict";
|
|
39715
|
+
if (item.source.caller_stable_id) stableIds.add(item.source.caller_stable_id);
|
|
39716
|
+
}
|
|
39717
|
+
if (!reason) return null;
|
|
39718
|
+
return items.map((item, index) => ({
|
|
39719
|
+
index,
|
|
39720
|
+
outcome: "rejected",
|
|
39721
|
+
external_id_hash: sourceIdentityHash(item.source),
|
|
39722
|
+
content_digest: sourceContentDigest(item.content ?? ""),
|
|
39723
|
+
reason_code: reason
|
|
39724
|
+
}));
|
|
39470
39725
|
}
|
|
39471
39726
|
|
|
39472
39727
|
// src/records/lifecycle-purge.ts
|
|
@@ -39586,8 +39841,8 @@ async function purgeRecordStoreGraph(store, selector, operationKey) {
|
|
|
39586
39841
|
}
|
|
39587
39842
|
|
|
39588
39843
|
// src/index.ts
|
|
39589
|
-
var VERSION = "2026.9.
|
|
39844
|
+
var VERSION = "2026.9.2";
|
|
39590
39845
|
|
|
39591
|
-
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
39846
|
+
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreRequest, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
39592
39847
|
//# sourceMappingURL=index.js.map
|
|
39593
39848
|
//# sourceMappingURL=index.js.map
|