@fortemi/core 2026.9.5 → 2026.9.6
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/dist/index.d.ts +1606 -1485
- package/dist/index.js +1757 -420
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/schemas/metadata-search/candidate/1.0.0/README.md +36 -0
- package/schemas/metadata-search/candidate/1.0.0/contract.receipt.json +38 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-locator.schema.json +50 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-resolution-vectors.json +355 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-resolution.schema.json +25 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-set-vectors.json +6095 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-set.schema.json +21 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-vectors.json +1603 -0
- package/schemas/metadata-search/candidate/1.0.0/predicate-vectors.json +919 -0
- package/schemas/metadata-search/candidate/1.0.0/predicates.schema.json +287 -0
- package/schemas/metadata-search/candidate/1.0.0/resolution.receipt.json +44 -0
- package/schemas/metadata-search/candidate/1.0.0/rest.receipt.json +51 -0
- package/schemas/metadata-search/candidate/1.0.0/search-rest-vectors.json +28 -0
- package/schemas/metadata-search/candidate/1.0.0/search-rest.schema.json +318 -0
- package/schemas/metadata-search/candidate/1.0.0/source.receipt.json +46 -0
- package/schemas/metadata-search/candidate/1.0.0/sql-scope-vectors.json +894 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { v7, v5 } from 'uuid';
|
|
2
2
|
import { sha256 } from '@noble/hashes/sha256';
|
|
3
3
|
import { blake3 } from '@noble/hashes/blake3';
|
|
4
|
-
import { bytesToHex } from '@noble/hashes/utils';
|
|
5
|
-
import
|
|
4
|
+
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
|
|
5
|
+
import Ajv20206 from 'ajv/dist/2020.js';
|
|
6
6
|
import { gzipSync, gunzipSync } from 'fflate';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
|
|
@@ -24,9 +24,9 @@ var __export = (target, all) => {
|
|
|
24
24
|
};
|
|
25
25
|
var __copyProps = (to, from, except, desc) => {
|
|
26
26
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
27
|
-
for (let
|
|
28
|
-
if (!__hasOwnProp.call(to,
|
|
29
|
-
__defProp(to,
|
|
27
|
+
for (let key3 of __getOwnPropNames(from))
|
|
28
|
+
if (!__hasOwnProp.call(to, key3) && key3 !== except)
|
|
29
|
+
__defProp(to, key3, { get: () => from[key3], enumerable: !(desc = __getOwnPropDesc(from, key3)) || desc.enumerable });
|
|
30
30
|
}
|
|
31
31
|
return to;
|
|
32
32
|
};
|
|
@@ -1991,19 +1991,19 @@ var require_point = __commonJS({
|
|
|
1991
1991
|
var Types = require_types();
|
|
1992
1992
|
var BinaryWriter = require_binarywriter();
|
|
1993
1993
|
var ZigZag = require_zigzag();
|
|
1994
|
-
function Point2(x, y,
|
|
1994
|
+
function Point2(x, y, z13, m, srid) {
|
|
1995
1995
|
Geometry2.call(this);
|
|
1996
1996
|
this.x = x;
|
|
1997
1997
|
this.y = y;
|
|
1998
|
-
this.z =
|
|
1998
|
+
this.z = z13;
|
|
1999
1999
|
this.m = m;
|
|
2000
2000
|
this.srid = srid;
|
|
2001
2001
|
this.hasZ = typeof this.z !== "undefined";
|
|
2002
2002
|
this.hasM = typeof this.m !== "undefined";
|
|
2003
2003
|
}
|
|
2004
2004
|
util.inherits(Point2, Geometry2);
|
|
2005
|
-
Point2.Z = function(x, y,
|
|
2006
|
-
var point = new Point2(x, y,
|
|
2005
|
+
Point2.Z = function(x, y, z13, srid) {
|
|
2006
|
+
var point = new Point2(x, y, z13, void 0, srid);
|
|
2007
2007
|
point.hasZ = true;
|
|
2008
2008
|
return point;
|
|
2009
2009
|
};
|
|
@@ -2012,8 +2012,8 @@ var require_point = __commonJS({
|
|
|
2012
2012
|
point.hasM = true;
|
|
2013
2013
|
return point;
|
|
2014
2014
|
};
|
|
2015
|
-
Point2.ZM = function(x, y,
|
|
2016
|
-
var point = new Point2(x, y,
|
|
2015
|
+
Point2.ZM = function(x, y, z13, m, srid) {
|
|
2016
|
+
var point = new Point2(x, y, z13, m, srid);
|
|
2017
2017
|
point.hasZ = true;
|
|
2018
2018
|
point.hasM = true;
|
|
2019
2019
|
return point;
|
|
@@ -2119,17 +2119,17 @@ var require_point = __commonJS({
|
|
|
2119
2119
|
Point2.prototype._writeTwkbPoint = function(twkb, precision, previousPoint) {
|
|
2120
2120
|
var x = this.x * precision.xyFactor;
|
|
2121
2121
|
var y = this.y * precision.xyFactor;
|
|
2122
|
-
var
|
|
2122
|
+
var z13 = this.z * precision.zFactor;
|
|
2123
2123
|
var m = this.m * precision.mFactor;
|
|
2124
2124
|
twkb.writeVarInt(ZigZag.encode(x - previousPoint.x));
|
|
2125
2125
|
twkb.writeVarInt(ZigZag.encode(y - previousPoint.y));
|
|
2126
2126
|
if (this.hasZ)
|
|
2127
|
-
twkb.writeVarInt(ZigZag.encode(
|
|
2127
|
+
twkb.writeVarInt(ZigZag.encode(z13 - previousPoint.z));
|
|
2128
2128
|
if (this.hasM)
|
|
2129
2129
|
twkb.writeVarInt(ZigZag.encode(m - previousPoint.m));
|
|
2130
2130
|
previousPoint.x = x;
|
|
2131
2131
|
previousPoint.y = y;
|
|
2132
|
-
previousPoint.z =
|
|
2132
|
+
previousPoint.z = z13;
|
|
2133
2133
|
previousPoint.m = m;
|
|
2134
2134
|
};
|
|
2135
2135
|
Point2.prototype._getWkbSize = function() {
|
|
@@ -3615,14 +3615,14 @@ var MemoryDatasetIngestStore = class {
|
|
|
3615
3615
|
receipts: /* @__PURE__ */ new Map()
|
|
3616
3616
|
};
|
|
3617
3617
|
const draft = {
|
|
3618
|
-
records: new Map([...existing.records].map(([
|
|
3619
|
-
receipts: new Map([...existing.receipts].map(([
|
|
3618
|
+
records: new Map([...existing.records].map(([key3, value]) => [key3, clone(value)])),
|
|
3619
|
+
receipts: new Map([...existing.receipts].map(([key3, value]) => [key3, clone(value)])),
|
|
3620
3620
|
...existing.checkpoint ? { checkpoint: clone(existing.checkpoint) } : {}
|
|
3621
3621
|
};
|
|
3622
3622
|
const transaction = {
|
|
3623
3623
|
getRecord: (id) => draft.records.get(id),
|
|
3624
3624
|
setRecord: (record) => draft.records.set(record.logicalId, clone(record)),
|
|
3625
|
-
getReceipt: (
|
|
3625
|
+
getReceipt: (key3) => draft.receipts.get(key3),
|
|
3626
3626
|
setReceipt: (receipt) => draft.receipts.set(receipt.idempotencyKey, clone(receipt)),
|
|
3627
3627
|
getCheckpoint: () => draft.checkpoint,
|
|
3628
3628
|
setCheckpoint: (checkpoint) => {
|
|
@@ -3650,7 +3650,7 @@ var MemoryDatasetIngestStore = class {
|
|
|
3650
3650
|
function canonicalJson(value) {
|
|
3651
3651
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
3652
3652
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
3653
|
-
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([
|
|
3653
|
+
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson(item)}`).join(",")}}`;
|
|
3654
3654
|
}
|
|
3655
3655
|
function digest(value) {
|
|
3656
3656
|
return computeHash(new TextEncoder().encode(canonicalJson(value)));
|
|
@@ -3819,11 +3819,11 @@ var DatasetIngestExecutor = class {
|
|
|
3819
3819
|
return this.store.getReceipt(datasetDestinationScopeKey(plan.destination), deriveDatasetIngestIdempotencyKey(plan, batch));
|
|
3820
3820
|
}
|
|
3821
3821
|
status(scope, expectedSourceRevision) {
|
|
3822
|
-
const
|
|
3823
|
-
const lastSuccessful = this.successes.get(
|
|
3822
|
+
const key3 = datasetDestinationScopeKey(scope);
|
|
3823
|
+
const lastSuccessful = this.successes.get(key3);
|
|
3824
3824
|
return {
|
|
3825
3825
|
scope: clone(scope),
|
|
3826
|
-
...this.attempts.get(
|
|
3826
|
+
...this.attempts.get(key3) ? { lastAttempt: clone(this.attempts.get(key3)) } : {},
|
|
3827
3827
|
...lastSuccessful ? { lastSuccessful: clone(lastSuccessful) } : {},
|
|
3828
3828
|
freshness: lastSuccessful ? expectedSourceRevision && expectedSourceRevision !== lastSuccessful.sourceRevision ? "stale" : "current" : "never"
|
|
3829
3829
|
};
|
|
@@ -3877,7 +3877,7 @@ function canonicalJson2(value) {
|
|
|
3877
3877
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
3878
3878
|
if (Array.isArray(value)) return `[${value.map(canonicalJson2).join(",")}]`;
|
|
3879
3879
|
const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
3880
|
-
return `{${entries.map(([
|
|
3880
|
+
return `{${entries.map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson2(item)}`).join(",")}}`;
|
|
3881
3881
|
}
|
|
3882
3882
|
function computeLineageDigest(value) {
|
|
3883
3883
|
return computeHash(new TextEncoder().encode(canonicalJson2(value)));
|
|
@@ -3957,9 +3957,9 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
3957
3957
|
if (item.payload !== void 0 && computeLineageDigest(item.payload) !== item.digest) {
|
|
3958
3958
|
throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence ${item.id} payload does not match ${item.digest}`);
|
|
3959
3959
|
}
|
|
3960
|
-
const
|
|
3961
|
-
this.ensureUnique(this.evidence,
|
|
3962
|
-
return this.append(this.evidence,
|
|
3960
|
+
const key3 = `${item.id}@${item.revision}`;
|
|
3961
|
+
this.ensureUnique(this.evidence, key3, "evidence revision");
|
|
3962
|
+
return this.append(this.evidence, key3, item);
|
|
3963
3963
|
}
|
|
3964
3964
|
appendAssertion(assertion) {
|
|
3965
3965
|
requireIdentity(assertion.id, "assertion.id");
|
|
@@ -3995,13 +3995,13 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
3995
3995
|
if (item.digest !== reference.digest) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence reference digest differs for ${reference.evidenceId}`);
|
|
3996
3996
|
if (reference.locator && reference.locator !== item.locator) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence locator differs for ${reference.evidenceId}`);
|
|
3997
3997
|
}
|
|
3998
|
-
const
|
|
3999
|
-
if (this.assertions.has(
|
|
3998
|
+
const key3 = `${assertion.id}@${assertion.revision}`;
|
|
3999
|
+
if (this.assertions.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate assertion revision ${key3}`);
|
|
4000
4000
|
const prior = [...this.assertions.values()].some((entry) => entry.value.id === assertion.id);
|
|
4001
4001
|
if (prior && !this.hasReplacementPermission(assertion.id, assertion.revision)) {
|
|
4002
4002
|
throw new LineageValidationError("CORRECTION_INVALID", `Assertion ${assertion.id} can only receive revision ${assertion.revision} after an explicit correction`);
|
|
4003
4003
|
}
|
|
4004
|
-
return this.append(this.assertions,
|
|
4004
|
+
return this.append(this.assertions, key3, assertion);
|
|
4005
4005
|
}
|
|
4006
4006
|
appendCorrection(correction) {
|
|
4007
4007
|
requireIdentity(correction.id, "correction.id");
|
|
@@ -4116,10 +4116,10 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
4116
4116
|
const correction = pending.splice(index, 1)[0];
|
|
4117
4117
|
ledger.appendCorrection(correction);
|
|
4118
4118
|
if (correction.replacementAssertionId && correction.replacementRevision) {
|
|
4119
|
-
const
|
|
4120
|
-
if (!ledger.assertions.has(
|
|
4121
|
-
const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` ===
|
|
4122
|
-
if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${
|
|
4119
|
+
const key3 = `${correction.replacementAssertionId}@${correction.replacementRevision}`;
|
|
4120
|
+
if (!ledger.assertions.has(key3)) {
|
|
4121
|
+
const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` === key3);
|
|
4122
|
+
if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${key3}`);
|
|
4123
4123
|
ledger.appendAssertion(replacement);
|
|
4124
4124
|
}
|
|
4125
4125
|
}
|
|
@@ -4167,19 +4167,19 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
4167
4167
|
}
|
|
4168
4168
|
});
|
|
4169
4169
|
}
|
|
4170
|
-
append(map,
|
|
4170
|
+
append(map, key3, value) {
|
|
4171
4171
|
this.sequence += 1;
|
|
4172
|
-
map.set(
|
|
4172
|
+
map.set(key3, { sequence: this.sequence, value: clone2(value) });
|
|
4173
4173
|
return this.sequence;
|
|
4174
4174
|
}
|
|
4175
|
-
ensureUnique(map,
|
|
4176
|
-
if (map.has(
|
|
4175
|
+
ensureUnique(map, key3, label) {
|
|
4176
|
+
if (map.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate ${label} identity ${key3}`);
|
|
4177
4177
|
}
|
|
4178
4178
|
visibleAt(map, snapshot) {
|
|
4179
|
-
return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([
|
|
4179
|
+
return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([key3, entry]) => [key3, clone2(entry.value)]));
|
|
4180
4180
|
}
|
|
4181
|
-
sorted(map,
|
|
4182
|
-
return [...map.values()].sort((left, right) =>
|
|
4181
|
+
sorted(map, key3 = (item) => item.id) {
|
|
4182
|
+
return [...map.values()].sort((left, right) => key3(left).localeCompare(key3(right))).map(clone2);
|
|
4183
4183
|
}
|
|
4184
4184
|
hasReplacementPermission(assertionId, revision) {
|
|
4185
4185
|
return [...this.corrections.values()].some((entry) => entry.value.action === "correct" && entry.value.replacementAssertionId === assertionId && entry.value.replacementRevision === revision);
|
|
@@ -4724,7 +4724,7 @@ var DATASET_EXECUTION_CAPABILITY_IDS = [
|
|
|
4724
4724
|
var ID_SET = new Set(DATASET_EXECUTION_CAPABILITY_IDS);
|
|
4725
4725
|
var LIMIT_KEYS = ["maxInputBytes", "maxRecordBytes", "maxBatchRecords", "maxConcurrency", "maxPageSize", "maxTraversalDepth"];
|
|
4726
4726
|
var versionPattern = new RegExp(schema_default.$defs.semver.pattern);
|
|
4727
|
-
var ajv = new
|
|
4727
|
+
var ajv = new Ajv20206({ strict: true, allErrors: false });
|
|
4728
4728
|
ajv.addSchema(schema_default);
|
|
4729
4729
|
var descriptorStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/descriptor" });
|
|
4730
4730
|
var requestStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/request" });
|
|
@@ -4767,8 +4767,8 @@ function compareVersions(left, right) {
|
|
|
4767
4767
|
function isSupported(capability) {
|
|
4768
4768
|
return capability !== void 0 && (capability.status === "supported" || capability.status === "experimental");
|
|
4769
4769
|
}
|
|
4770
|
-
function structuralDiagnostics(
|
|
4771
|
-
return (
|
|
4770
|
+
function structuralDiagnostics(validate4, prefix = "") {
|
|
4771
|
+
return (validate4.errors ?? []).slice(0, 8).map((error) => ({
|
|
4772
4772
|
code: "DESCRIPTOR_INVALID",
|
|
4773
4773
|
path: (prefix + error.instancePath).slice(0, 256),
|
|
4774
4774
|
message: "Invalid capability wire structure: " + error.keyword
|
|
@@ -4801,10 +4801,10 @@ function validateDatasetExecutionDescriptor(descriptor) {
|
|
|
4801
4801
|
diagnostics.push({ code: "CAPABILITY_DUPLICATE", capability: capability.id, path: `/capabilities/${index}/id`, message: `Capability ${capability.id} is declared more than once` });
|
|
4802
4802
|
}
|
|
4803
4803
|
capabilities.set(capability.id, capability);
|
|
4804
|
-
for (const
|
|
4805
|
-
const value = capability.limits?.[
|
|
4804
|
+
for (const key3 of LIMIT_KEYS) {
|
|
4805
|
+
const value = capability.limits?.[key3];
|
|
4806
4806
|
if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0)) {
|
|
4807
|
-
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${
|
|
4807
|
+
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${key3}`, message: `${key3} must be a non-negative safe integer` });
|
|
4808
4808
|
}
|
|
4809
4809
|
}
|
|
4810
4810
|
if (capability.status !== "unsupported" && capability.evidence.length === 0) {
|
|
@@ -4875,10 +4875,10 @@ function assessRequirement(requirement, capabilities) {
|
|
|
4875
4875
|
return { ok: false, reason: "version-insufficient", diagnostics: [{ code: "CAPABILITY_VERSION_INSUFFICIENT", capability: requirement.id, message: `${capability.version} does not satisfy ${requirement.minimumVersion}` }] };
|
|
4876
4876
|
}
|
|
4877
4877
|
}
|
|
4878
|
-
for (const
|
|
4879
|
-
const required = requirement.minimumLimits?.[
|
|
4880
|
-
if (required !== void 0 && (capability.limits?.[
|
|
4881
|
-
return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${
|
|
4878
|
+
for (const key3 of LIMIT_KEYS) {
|
|
4879
|
+
const required = requirement.minimumLimits?.[key3];
|
|
4880
|
+
if (required !== void 0 && (capability.limits?.[key3] ?? -1) < required) {
|
|
4881
|
+
return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${key3}`, message: `${key3} does not satisfy ${required}` }] };
|
|
4882
4882
|
}
|
|
4883
4883
|
}
|
|
4884
4884
|
return { ok: true, diagnostics: [] };
|
|
@@ -4986,7 +4986,7 @@ var encoder = new TextEncoder();
|
|
|
4986
4986
|
function canonicalJson3(value) {
|
|
4987
4987
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
4988
4988
|
if (Array.isArray(value)) return `[${value.map(canonicalJson3).join(",")}]`;
|
|
4989
|
-
return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([
|
|
4989
|
+
return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson3(item)}`).join(",")}}`;
|
|
4990
4990
|
}
|
|
4991
4991
|
function digestDatasetMaterializationValue(value) {
|
|
4992
4992
|
return computeHash(encoder.encode(canonicalJson3(value)));
|
|
@@ -5077,7 +5077,7 @@ async function executeDatasetMaterialization(request, runtime, adapter, authoriz
|
|
|
5077
5077
|
}
|
|
5078
5078
|
const selected = [request.profile, ...options.fallbackProfiles ?? []].find((item) => item.id === negotiation.selectedProfile);
|
|
5079
5079
|
try {
|
|
5080
|
-
const validateConfiguration = new
|
|
5080
|
+
const validateConfiguration = new Ajv20206({ strict: true, allErrors: true }).compile(selected.configurationSchema);
|
|
5081
5081
|
if (!validateConfiguration(request.configuration)) {
|
|
5082
5082
|
throw new DatasetMaterializationError("CONFIGURATION_INVALID", `Configuration does not satisfy ${selected.id}: ${JSON.stringify(validateConfiguration.errors)}`);
|
|
5083
5083
|
}
|
|
@@ -6877,7 +6877,7 @@ function nativeIdentityKey(spec, row) {
|
|
|
6877
6877
|
// src/migrations/0031_native_shard_lineage.ts
|
|
6878
6878
|
var triggers = Object.entries(nativeIdentities).flatMap(([component, spec]) => (component === "links" ? ["link", "link_url_target"] : [spec.table]).map((table) => `
|
|
6879
6879
|
CREATE TRIGGER native_lineage_delete AFTER DELETE ON ${table} FOR EACH ROW
|
|
6880
|
-
EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((
|
|
6880
|
+
EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((key3) => `'${key3}'`).join(", ")});`)).join("\n");
|
|
6881
6881
|
var migration0031 = {
|
|
6882
6882
|
version: 31,
|
|
6883
6883
|
name: "0031_native_shard_lineage",
|
|
@@ -6923,6 +6923,58 @@ var migration0032 = {
|
|
|
6923
6923
|
`
|
|
6924
6924
|
};
|
|
6925
6925
|
|
|
6926
|
+
// src/migrations/0033_typed_metadata_search.ts
|
|
6927
|
+
init_geometry_buffer();
|
|
6928
|
+
var migration0033 = {
|
|
6929
|
+
version: 33,
|
|
6930
|
+
name: "0033_typed_metadata_search",
|
|
6931
|
+
sql: `
|
|
6932
|
+
CREATE FUNCTION public.metadata_search_order_key_v1(value jsonb)
|
|
6933
|
+
RETURNS numeric LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
|
|
6934
|
+
SET search_path = pg_catalog
|
|
6935
|
+
AS $function$
|
|
6936
|
+
SELECT CASE jsonb_typeof(value)
|
|
6937
|
+
WHEN 'number' THEN trunc(greatest(-1e16::numeric,
|
|
6938
|
+
least(1e16::numeric, (value #>> '{}')::numeric)), 18)
|
|
6939
|
+
WHEN 'boolean' THEN CASE WHEN value = 'true'::jsonb THEN 1::numeric ELSE 0::numeric END
|
|
6940
|
+
ELSE NULL::numeric
|
|
6941
|
+
END
|
|
6942
|
+
$function$;
|
|
6943
|
+
|
|
6944
|
+
CREATE FUNCTION public.metadata_search_text_key_v1(value jsonb)
|
|
6945
|
+
RETURNS text LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
|
|
6946
|
+
SET search_path = pg_catalog
|
|
6947
|
+
AS $function$
|
|
6948
|
+
SELECT CASE WHEN jsonb_typeof(value) = 'string'
|
|
6949
|
+
THEN left(value #>> '{}', 256) ELSE NULL::text END
|
|
6950
|
+
$function$;
|
|
6951
|
+
|
|
6952
|
+
DO $metadata_indexes$
|
|
6953
|
+
DECLARE metadata_path text;
|
|
6954
|
+
BEGIN
|
|
6955
|
+
FOREACH metadata_path IN ARRAY ARRAY['provider', 'model', 'role', 'event_kind', 'sensitivity']
|
|
6956
|
+
LOOP
|
|
6957
|
+
-- Superseded unbounded indexes can reject large values before query rechecks.
|
|
6958
|
+
EXECUTE format('DROP INDEX %I', 'idx_note_metadata_' || metadata_path);
|
|
6959
|
+
EXECUTE format('DROP INDEX %I', 'idx_note_native_metadata_' || metadata_path);
|
|
6960
|
+
EXECUTE format(
|
|
6961
|
+
'CREATE INDEX %I ON note (
|
|
6962
|
+
(jsonb_typeof(metadata -> %L)),
|
|
6963
|
+
(public.metadata_search_order_key_v1(metadata -> %L)),
|
|
6964
|
+
(public.metadata_search_text_key_v1(metadata -> %L) COLLATE "C"))',
|
|
6965
|
+
'idx_note_metadata_' || metadata_path || '_v1', metadata_path, metadata_path, metadata_path);
|
|
6966
|
+
END LOOP;
|
|
6967
|
+
END
|
|
6968
|
+
$metadata_indexes$;
|
|
6969
|
+
|
|
6970
|
+
CREATE INDEX idx_source_identity_metadata_run_v1 ON source_identity
|
|
6971
|
+
(tenant_id, import_run_id COLLATE "C", note_id);
|
|
6972
|
+
CREATE INDEX idx_source_identity_metadata_note_v1 ON source_identity (tenant_id, note_id);
|
|
6973
|
+
UPDATE metadata_index_path SET value_type = 'json-scalar-v1', indexed_at = now()
|
|
6974
|
+
WHERE path IN ('provider', 'model', 'role', 'event_kind', 'sensitivity');
|
|
6975
|
+
`
|
|
6976
|
+
};
|
|
6977
|
+
|
|
6926
6978
|
// src/migrations/index.ts
|
|
6927
6979
|
var allMigrations = [
|
|
6928
6980
|
migration0001,
|
|
@@ -6956,7 +7008,8 @@ var allMigrations = [
|
|
|
6956
7008
|
migration0029,
|
|
6957
7009
|
migration0030,
|
|
6958
7010
|
migration0031,
|
|
6959
|
-
migration0032
|
|
7011
|
+
migration0032,
|
|
7012
|
+
migration0033
|
|
6960
7013
|
];
|
|
6961
7014
|
|
|
6962
7015
|
// src/data-archive.ts
|
|
@@ -7558,6 +7611,137 @@ var NotesRepository = class {
|
|
|
7558
7611
|
// src/repositories/search-repository.ts
|
|
7559
7612
|
init_geometry_buffer();
|
|
7560
7613
|
|
|
7614
|
+
// src/repositories/search-evidence-repository.ts
|
|
7615
|
+
init_geometry_buffer();
|
|
7616
|
+
|
|
7617
|
+
// src/search-evidence.ts
|
|
7618
|
+
init_geometry_buffer();
|
|
7619
|
+
|
|
7620
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-locator.schema.json
|
|
7621
|
+
var evidence_locator_schema_default = {
|
|
7622
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7623
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-locator.schema.json",
|
|
7624
|
+
title: "Candidate search evidence locator",
|
|
7625
|
+
type: "object",
|
|
7626
|
+
additionalProperties: false,
|
|
7627
|
+
required: ["version", "note_id", "unit", "content_digest", "span"],
|
|
7628
|
+
properties: {
|
|
7629
|
+
version: { const: "1.0.0" },
|
|
7630
|
+
note_id: { $ref: "#/$defs/identifier" },
|
|
7631
|
+
unit: {
|
|
7632
|
+
type: "object",
|
|
7633
|
+
additionalProperties: false,
|
|
7634
|
+
required: ["kind", "id", "index"],
|
|
7635
|
+
properties: {
|
|
7636
|
+
kind: { enum: ["current", "title", "embedding", "attachment"] },
|
|
7637
|
+
id: { $ref: "#/$defs/identifier" },
|
|
7638
|
+
index: { type: "integer", minimum: 0, maximum: 2147483647 }
|
|
7639
|
+
},
|
|
7640
|
+
if: { properties: { kind: { enum: ["current", "title", "attachment"] } } },
|
|
7641
|
+
then: { properties: { index: { const: 0 } } }
|
|
7642
|
+
},
|
|
7643
|
+
content_digest: { $ref: "#/$defs/digest" },
|
|
7644
|
+
span: {
|
|
7645
|
+
type: "object",
|
|
7646
|
+
additionalProperties: false,
|
|
7647
|
+
required: ["unit", "start", "end"],
|
|
7648
|
+
properties: {
|
|
7649
|
+
unit: { const: "utf8-bytes" },
|
|
7650
|
+
start: { type: "integer", minimum: 0, maximum: 16777216 },
|
|
7651
|
+
end: { type: "integer", minimum: 0, maximum: 16777216 }
|
|
7652
|
+
}
|
|
7653
|
+
},
|
|
7654
|
+
source: {
|
|
7655
|
+
type: "object",
|
|
7656
|
+
additionalProperties: false,
|
|
7657
|
+
required: ["namespace", "external_id_hash", "import_run_id", "schema_version"],
|
|
7658
|
+
properties: {
|
|
7659
|
+
namespace: { $ref: "#/$defs/identifier" },
|
|
7660
|
+
external_id_hash: { $ref: "#/$defs/digest" },
|
|
7661
|
+
import_run_id: { $ref: "#/$defs/identifier" },
|
|
7662
|
+
schema_version: { $ref: "#/$defs/identifier" }
|
|
7663
|
+
}
|
|
7664
|
+
}
|
|
7665
|
+
},
|
|
7666
|
+
$defs: {
|
|
7667
|
+
identifier: { type: "string", minLength: 1, maxLength: 200, pattern: "^[^\\u0000]+$" },
|
|
7668
|
+
digest: { type: "string", pattern: "^sha256:[a-f0-9]{64}$" }
|
|
7669
|
+
}
|
|
7670
|
+
};
|
|
7671
|
+
|
|
7672
|
+
// src/search-evidence.ts
|
|
7673
|
+
var MAX_EVIDENCE_BYTES = 16 * 1024 * 1024;
|
|
7674
|
+
var validateSchema = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(evidence_locator_schema_default);
|
|
7675
|
+
var encoder2 = new TextEncoder();
|
|
7676
|
+
var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
7677
|
+
var invalid = () => new Error("SEARCH_EVIDENCE_INVALID");
|
|
7678
|
+
var unavailable = () => new Error("SEARCH_EVIDENCE_UNAVAILABLE");
|
|
7679
|
+
function wellFormed(value) {
|
|
7680
|
+
for (let i = 0; i < value.length; i++) {
|
|
7681
|
+
const code = value.charCodeAt(i);
|
|
7682
|
+
if (code >= 55296 && code <= 56319) {
|
|
7683
|
+
const next = value.charCodeAt(++i);
|
|
7684
|
+
if (!(next >= 56320 && next <= 57343)) return false;
|
|
7685
|
+
} else if (code >= 56320 && code <= 57343) return false;
|
|
7686
|
+
}
|
|
7687
|
+
return true;
|
|
7688
|
+
}
|
|
7689
|
+
function parseSearchEvidenceLocator(value) {
|
|
7690
|
+
if (!validateSchema(value)) throw invalid();
|
|
7691
|
+
const locator = value;
|
|
7692
|
+
const strings = [locator.note_id, locator.unit.id, ...Object.values(locator.source ?? {})];
|
|
7693
|
+
if (!strings.every(wellFormed) || locator.span.start > locator.span.end) throw invalid();
|
|
7694
|
+
if ((locator.unit.kind === "current" || locator.unit.kind === "title") && locator.unit.id !== locator.note_id) throw invalid();
|
|
7695
|
+
const copy = {
|
|
7696
|
+
version: locator.version,
|
|
7697
|
+
note_id: locator.note_id,
|
|
7698
|
+
unit: Object.freeze({ kind: locator.unit.kind, id: locator.unit.id, index: locator.unit.index }),
|
|
7699
|
+
content_digest: locator.content_digest,
|
|
7700
|
+
span: Object.freeze({ unit: locator.span.unit, start: locator.span.start, end: locator.span.end }),
|
|
7701
|
+
...locator.source === void 0 ? {} : { source: Object.freeze({ ...locator.source }) }
|
|
7702
|
+
};
|
|
7703
|
+
return Object.freeze(copy);
|
|
7704
|
+
}
|
|
7705
|
+
function textBytes(content) {
|
|
7706
|
+
if (typeof content !== "string" || content.length > MAX_EVIDENCE_BYTES || !wellFormed(content)) return null;
|
|
7707
|
+
const bytes = encoder2.encode(content);
|
|
7708
|
+
return bytes.length <= MAX_EVIDENCE_BYTES ? bytes : null;
|
|
7709
|
+
}
|
|
7710
|
+
function spanText(bytes, start, end) {
|
|
7711
|
+
if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || start > end || end > bytes.length) return null;
|
|
7712
|
+
if (start < bytes.length && (bytes[start] & 192) === 128 || end < bytes.length && (bytes[end] & 192) === 128) return null;
|
|
7713
|
+
try {
|
|
7714
|
+
return decoder.decode(bytes.subarray(start, end));
|
|
7715
|
+
} catch {
|
|
7716
|
+
return null;
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
function bindSearchEvidence(text, start, end) {
|
|
7720
|
+
const bytes = textBytes(text.content);
|
|
7721
|
+
if (!bytes || spanText(bytes, start, end) === null) throw invalid();
|
|
7722
|
+
return parseSearchEvidenceLocator({
|
|
7723
|
+
version: "1.0.0",
|
|
7724
|
+
note_id: text.note_id,
|
|
7725
|
+
unit: text.unit,
|
|
7726
|
+
content_digest: computeHash(bytes),
|
|
7727
|
+
span: { unit: "utf8-bytes", start, end },
|
|
7728
|
+
...text.source === void 0 ? {} : { source: text.source }
|
|
7729
|
+
});
|
|
7730
|
+
}
|
|
7731
|
+
function sameSource(a, b) {
|
|
7732
|
+
if (!a || !b) return a === b;
|
|
7733
|
+
return a.namespace === b.namespace && a.external_id_hash === b.external_id_hash && a.import_run_id === b.import_run_id && a.schema_version === b.schema_version;
|
|
7734
|
+
}
|
|
7735
|
+
function resolveSearchEvidence(value, text) {
|
|
7736
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
7737
|
+
if (!text || locator.note_id !== text.note_id || locator.unit.kind !== text.unit.kind || locator.unit.id !== text.unit.id || locator.unit.index !== text.unit.index || !sameSource(locator.source, text.source)) throw unavailable();
|
|
7738
|
+
const bytes = textBytes(text.content);
|
|
7739
|
+
if (!bytes || computeHash(bytes) !== locator.content_digest) throw unavailable();
|
|
7740
|
+
const result = spanText(bytes, locator.span.start, locator.span.end);
|
|
7741
|
+
if (result === null) throw unavailable();
|
|
7742
|
+
return result;
|
|
7743
|
+
}
|
|
7744
|
+
|
|
7561
7745
|
// src/repositories/condition-builder.ts
|
|
7562
7746
|
init_geometry_buffer();
|
|
7563
7747
|
function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
@@ -7573,6 +7757,11 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7573
7757
|
);
|
|
7574
7758
|
params.push(options.tags);
|
|
7575
7759
|
}
|
|
7760
|
+
if (options.tagsAll?.length) {
|
|
7761
|
+
conditions.push(`NOT EXISTS (SELECT 1 FROM unnest($${idx++}::text[]) wanted(tag)
|
|
7762
|
+
WHERE NOT EXISTS (SELECT 1 FROM note_tag nt WHERE nt.note_id = n.id AND nt.tag = wanted.tag))`);
|
|
7763
|
+
params.push(options.tagsAll);
|
|
7764
|
+
}
|
|
7576
7765
|
if (options.collection_id) {
|
|
7577
7766
|
conditions.push(
|
|
7578
7767
|
`EXISTS (SELECT 1 FROM collection_note cn WHERE cn.note_id = n.id AND cn.collection_id = $${idx++})`
|
|
@@ -7603,6 +7792,10 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7603
7792
|
conditions.push(`n.source = $${idx++}`);
|
|
7604
7793
|
params.push(options.source);
|
|
7605
7794
|
}
|
|
7795
|
+
if (options.sources?.length) {
|
|
7796
|
+
conditions.push(`n.source = ANY($${idx++}::text[])`);
|
|
7797
|
+
params.push(options.sources);
|
|
7798
|
+
}
|
|
7606
7799
|
if (options.visibility) {
|
|
7607
7800
|
conditions.push(`n.visibility = $${idx++}`);
|
|
7608
7801
|
params.push(options.visibility);
|
|
@@ -7610,6 +7803,657 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7610
7803
|
return { conditions, params, nextIdx: idx };
|
|
7611
7804
|
}
|
|
7612
7805
|
|
|
7806
|
+
// src/repositories/metadata-predicates.ts
|
|
7807
|
+
init_geometry_buffer();
|
|
7808
|
+
|
|
7809
|
+
// schemas/metadata-search/candidate/1.0.0/predicates.schema.json
|
|
7810
|
+
var predicates_schema_default = {
|
|
7811
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7812
|
+
$id: "https://fortemi.dev/schemas/metadata-search/candidate/1.0.0/predicates.schema.json",
|
|
7813
|
+
title: "Candidate typed metadata predicates",
|
|
7814
|
+
type: "array",
|
|
7815
|
+
maxItems: 8,
|
|
7816
|
+
items: {
|
|
7817
|
+
$ref: "#/$defs/predicate"
|
|
7818
|
+
},
|
|
7819
|
+
$defs: {
|
|
7820
|
+
scalar: {
|
|
7821
|
+
oneOf: [
|
|
7822
|
+
{
|
|
7823
|
+
type: "string",
|
|
7824
|
+
maxLength: 256,
|
|
7825
|
+
pattern: "^[^\\u0000]*$"
|
|
7826
|
+
},
|
|
7827
|
+
{
|
|
7828
|
+
type: "number",
|
|
7829
|
+
minimum: -9007199254740991,
|
|
7830
|
+
maximum: 9007199254740991
|
|
7831
|
+
},
|
|
7832
|
+
{
|
|
7833
|
+
type: "boolean"
|
|
7834
|
+
},
|
|
7835
|
+
{
|
|
7836
|
+
type: "null"
|
|
7837
|
+
}
|
|
7838
|
+
]
|
|
7839
|
+
},
|
|
7840
|
+
bound: {
|
|
7841
|
+
oneOf: [
|
|
7842
|
+
{
|
|
7843
|
+
type: "string",
|
|
7844
|
+
maxLength: 256,
|
|
7845
|
+
pattern: "^[^\\u0000]*$"
|
|
7846
|
+
},
|
|
7847
|
+
{
|
|
7848
|
+
type: "number",
|
|
7849
|
+
minimum: -9007199254740991,
|
|
7850
|
+
maximum: 9007199254740991
|
|
7851
|
+
}
|
|
7852
|
+
]
|
|
7853
|
+
},
|
|
7854
|
+
predicate: {
|
|
7855
|
+
oneOf: [
|
|
7856
|
+
{
|
|
7857
|
+
type: "object",
|
|
7858
|
+
additionalProperties: false,
|
|
7859
|
+
required: [
|
|
7860
|
+
"path",
|
|
7861
|
+
"op",
|
|
7862
|
+
"value"
|
|
7863
|
+
],
|
|
7864
|
+
properties: {
|
|
7865
|
+
path: {
|
|
7866
|
+
enum: [
|
|
7867
|
+
"provider",
|
|
7868
|
+
"model",
|
|
7869
|
+
"role",
|
|
7870
|
+
"event_kind",
|
|
7871
|
+
"sensitivity",
|
|
7872
|
+
"import_run_id"
|
|
7873
|
+
]
|
|
7874
|
+
},
|
|
7875
|
+
op: {
|
|
7876
|
+
const: "eq"
|
|
7877
|
+
},
|
|
7878
|
+
value: {
|
|
7879
|
+
$ref: "#/$defs/scalar"
|
|
7880
|
+
}
|
|
7881
|
+
},
|
|
7882
|
+
allOf: [
|
|
7883
|
+
{
|
|
7884
|
+
if: {
|
|
7885
|
+
properties: {
|
|
7886
|
+
path: {
|
|
7887
|
+
const: "import_run_id"
|
|
7888
|
+
}
|
|
7889
|
+
}
|
|
7890
|
+
},
|
|
7891
|
+
then: {
|
|
7892
|
+
properties: {
|
|
7893
|
+
value: {
|
|
7894
|
+
type: "string",
|
|
7895
|
+
maxLength: 200,
|
|
7896
|
+
pattern: "^[^\\u0000]*$",
|
|
7897
|
+
minLength: 1
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
}
|
|
7902
|
+
]
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
type: "object",
|
|
7906
|
+
additionalProperties: false,
|
|
7907
|
+
required: [
|
|
7908
|
+
"path",
|
|
7909
|
+
"op",
|
|
7910
|
+
"value"
|
|
7911
|
+
],
|
|
7912
|
+
properties: {
|
|
7913
|
+
path: {
|
|
7914
|
+
enum: [
|
|
7915
|
+
"provider",
|
|
7916
|
+
"model",
|
|
7917
|
+
"role",
|
|
7918
|
+
"event_kind",
|
|
7919
|
+
"sensitivity",
|
|
7920
|
+
"import_run_id"
|
|
7921
|
+
]
|
|
7922
|
+
},
|
|
7923
|
+
op: {
|
|
7924
|
+
const: "in"
|
|
7925
|
+
},
|
|
7926
|
+
value: {
|
|
7927
|
+
type: "array",
|
|
7928
|
+
maxItems: 32,
|
|
7929
|
+
items: {
|
|
7930
|
+
$ref: "#/$defs/scalar"
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
},
|
|
7934
|
+
allOf: [
|
|
7935
|
+
{
|
|
7936
|
+
if: {
|
|
7937
|
+
properties: {
|
|
7938
|
+
path: {
|
|
7939
|
+
const: "import_run_id"
|
|
7940
|
+
}
|
|
7941
|
+
}
|
|
7942
|
+
},
|
|
7943
|
+
then: {
|
|
7944
|
+
properties: {
|
|
7945
|
+
value: {
|
|
7946
|
+
type: "array",
|
|
7947
|
+
items: {
|
|
7948
|
+
type: "string",
|
|
7949
|
+
maxLength: 200,
|
|
7950
|
+
pattern: "^[^\\u0000]*$",
|
|
7951
|
+
minLength: 1
|
|
7952
|
+
}
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7957
|
+
]
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
type: "object",
|
|
7961
|
+
additionalProperties: false,
|
|
7962
|
+
required: [
|
|
7963
|
+
"path",
|
|
7964
|
+
"op"
|
|
7965
|
+
],
|
|
7966
|
+
properties: {
|
|
7967
|
+
path: {
|
|
7968
|
+
enum: [
|
|
7969
|
+
"provider",
|
|
7970
|
+
"model",
|
|
7971
|
+
"role",
|
|
7972
|
+
"event_kind",
|
|
7973
|
+
"sensitivity",
|
|
7974
|
+
"import_run_id"
|
|
7975
|
+
]
|
|
7976
|
+
},
|
|
7977
|
+
op: {
|
|
7978
|
+
const: "range"
|
|
7979
|
+
},
|
|
7980
|
+
gte: {
|
|
7981
|
+
$ref: "#/$defs/bound"
|
|
7982
|
+
},
|
|
7983
|
+
lte: {
|
|
7984
|
+
$ref: "#/$defs/bound"
|
|
7985
|
+
}
|
|
7986
|
+
},
|
|
7987
|
+
anyOf: [
|
|
7988
|
+
{
|
|
7989
|
+
properties: {
|
|
7990
|
+
gte: {
|
|
7991
|
+
$ref: "#/$defs/bound"
|
|
7992
|
+
}
|
|
7993
|
+
},
|
|
7994
|
+
required: [
|
|
7995
|
+
"gte"
|
|
7996
|
+
]
|
|
7997
|
+
},
|
|
7998
|
+
{
|
|
7999
|
+
properties: {
|
|
8000
|
+
lte: {
|
|
8001
|
+
$ref: "#/$defs/bound"
|
|
8002
|
+
}
|
|
8003
|
+
},
|
|
8004
|
+
required: [
|
|
8005
|
+
"lte"
|
|
8006
|
+
]
|
|
8007
|
+
}
|
|
8008
|
+
],
|
|
8009
|
+
oneOf: [
|
|
8010
|
+
{
|
|
8011
|
+
properties: {
|
|
8012
|
+
gte: {
|
|
8013
|
+
type: "string",
|
|
8014
|
+
maxLength: 256,
|
|
8015
|
+
pattern: "^[^\\u0000]*$"
|
|
8016
|
+
},
|
|
8017
|
+
lte: {
|
|
8018
|
+
type: "string",
|
|
8019
|
+
maxLength: 256,
|
|
8020
|
+
pattern: "^[^\\u0000]*$"
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
},
|
|
8024
|
+
{
|
|
8025
|
+
properties: {
|
|
8026
|
+
gte: {
|
|
8027
|
+
type: "number",
|
|
8028
|
+
minimum: -9007199254740991,
|
|
8029
|
+
maximum: 9007199254740991
|
|
8030
|
+
},
|
|
8031
|
+
lte: {
|
|
8032
|
+
type: "number",
|
|
8033
|
+
minimum: -9007199254740991,
|
|
8034
|
+
maximum: 9007199254740991
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
}
|
|
8038
|
+
],
|
|
8039
|
+
allOf: [
|
|
8040
|
+
{
|
|
8041
|
+
if: {
|
|
8042
|
+
properties: {
|
|
8043
|
+
path: {
|
|
8044
|
+
const: "import_run_id"
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
},
|
|
8048
|
+
then: {
|
|
8049
|
+
properties: {
|
|
8050
|
+
gte: {
|
|
8051
|
+
type: "string",
|
|
8052
|
+
maxLength: 200,
|
|
8053
|
+
pattern: "^[^\\u0000]*$",
|
|
8054
|
+
minLength: 1
|
|
8055
|
+
},
|
|
8056
|
+
lte: {
|
|
8057
|
+
type: "string",
|
|
8058
|
+
maxLength: 200,
|
|
8059
|
+
pattern: "^[^\\u0000]*$",
|
|
8060
|
+
minLength: 1
|
|
8061
|
+
}
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
]
|
|
8066
|
+
},
|
|
8067
|
+
{
|
|
8068
|
+
type: "object",
|
|
8069
|
+
additionalProperties: false,
|
|
8070
|
+
required: [
|
|
8071
|
+
"path",
|
|
8072
|
+
"op"
|
|
8073
|
+
],
|
|
8074
|
+
properties: {
|
|
8075
|
+
path: {
|
|
8076
|
+
enum: [
|
|
8077
|
+
"provider",
|
|
8078
|
+
"model",
|
|
8079
|
+
"role",
|
|
8080
|
+
"event_kind",
|
|
8081
|
+
"sensitivity",
|
|
8082
|
+
"import_run_id"
|
|
8083
|
+
]
|
|
8084
|
+
},
|
|
8085
|
+
op: {
|
|
8086
|
+
const: "exists"
|
|
8087
|
+
},
|
|
8088
|
+
value: {
|
|
8089
|
+
type: "boolean"
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
]
|
|
8094
|
+
}
|
|
8095
|
+
}
|
|
8096
|
+
};
|
|
8097
|
+
|
|
8098
|
+
// src/repositories/metadata-predicates.ts
|
|
8099
|
+
var REGISTERED_METADATA_PATHS = [
|
|
8100
|
+
"provider",
|
|
8101
|
+
"model",
|
|
8102
|
+
"role",
|
|
8103
|
+
"event_kind",
|
|
8104
|
+
"sensitivity",
|
|
8105
|
+
"import_run_id"
|
|
8106
|
+
];
|
|
8107
|
+
var validateSchema2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(predicates_schema_default);
|
|
8108
|
+
function compareStrings(left, right) {
|
|
8109
|
+
const a = Array.from(left, (char) => char.codePointAt(0));
|
|
8110
|
+
const b = Array.from(right, (char) => char.codePointAt(0));
|
|
8111
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
8112
|
+
if (a[i] !== b[i]) return a[i] - b[i];
|
|
8113
|
+
}
|
|
8114
|
+
return a.length - b.length;
|
|
8115
|
+
}
|
|
8116
|
+
function validateMetadataPredicates(value) {
|
|
8117
|
+
if (!validateSchema2(value)) throw new Error("METADATA_PREDICATES_INVALID");
|
|
8118
|
+
const predicates = value;
|
|
8119
|
+
for (const predicate of predicates) {
|
|
8120
|
+
const values = predicate.op === "range" ? [predicate.gte, predicate.lte] : predicate.op === "in" ? predicate.value : [predicate.value];
|
|
8121
|
+
for (const scalar of values) {
|
|
8122
|
+
if (typeof scalar === "string" && Array.from(scalar).some((char) => {
|
|
8123
|
+
const code = char.codePointAt(0);
|
|
8124
|
+
return code >= 55296 && code <= 57343;
|
|
8125
|
+
})) throw new Error("METADATA_PREDICATES_INVALID");
|
|
8126
|
+
}
|
|
8127
|
+
}
|
|
8128
|
+
for (const predicate of predicates) {
|
|
8129
|
+
if (predicate.op !== "range" || predicate.gte === void 0 || predicate.lte === void 0) continue;
|
|
8130
|
+
const reversed = typeof predicate.gte === "string" ? compareStrings(predicate.gte, predicate.lte) > 0 : predicate.gte > predicate.lte;
|
|
8131
|
+
if (reversed) throw new Error("METADATA_RANGE_INVALID");
|
|
8132
|
+
}
|
|
8133
|
+
}
|
|
8134
|
+
function predicateSql(predicate, compare, exists) {
|
|
8135
|
+
switch (predicate.op) {
|
|
8136
|
+
case "eq":
|
|
8137
|
+
return compare(predicate.value, "=");
|
|
8138
|
+
case "in":
|
|
8139
|
+
return predicate.value.length ? `(${predicate.value.map((value) => compare(value, "=")).join(" OR ")})` : "FALSE";
|
|
8140
|
+
case "range":
|
|
8141
|
+
return `(${[
|
|
8142
|
+
predicate.gte === void 0 ? null : compare(predicate.gte, ">="),
|
|
8143
|
+
predicate.lte === void 0 ? null : compare(predicate.lte, "<=")
|
|
8144
|
+
].filter(Boolean).join(" AND ")})`;
|
|
8145
|
+
case "exists":
|
|
8146
|
+
return predicate.value === false ? `NOT (${exists})` : exists;
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
8149
|
+
function buildMetadataSourceConditions(options, startIdx) {
|
|
8150
|
+
const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
|
|
8151
|
+
validateMetadataPredicates(predicates);
|
|
8152
|
+
const params = [options.tenant_id ?? "default"];
|
|
8153
|
+
let idx = startIdx + 1;
|
|
8154
|
+
const conditions = [
|
|
8155
|
+
`si.note_id = n.id`,
|
|
8156
|
+
`si.tenant_id = $${startIdx}`,
|
|
8157
|
+
"si.archive_id IS NOT DISTINCT FROM n.archive_id",
|
|
8158
|
+
"si.import_run_id IS NOT NULL"
|
|
8159
|
+
];
|
|
8160
|
+
for (const predicate of predicates.filter((p) => p.path === "import_run_id")) {
|
|
8161
|
+
conditions.push(predicateSql(predicate, (value, op) => {
|
|
8162
|
+
params.push(value);
|
|
8163
|
+
return `si.import_run_id COLLATE "C" ${op} $${idx++}::text COLLATE "C"`;
|
|
8164
|
+
}, "si.import_run_id IS NOT NULL"));
|
|
8165
|
+
}
|
|
8166
|
+
return { conditions, joins: [], params, nextIdx: idx };
|
|
8167
|
+
}
|
|
8168
|
+
function buildMetadataPredicateConditions(options, startIdx) {
|
|
8169
|
+
const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
|
|
8170
|
+
validateMetadataPredicates(predicates);
|
|
8171
|
+
const conditions = [];
|
|
8172
|
+
const params = [];
|
|
8173
|
+
const joins = [];
|
|
8174
|
+
let idx = startIdx;
|
|
8175
|
+
if (options.archive_id !== void 0) {
|
|
8176
|
+
conditions.push(`n.archive_id IS NOT DISTINCT FROM $${idx++}::text`);
|
|
8177
|
+
params.push(options.archive_id);
|
|
8178
|
+
}
|
|
8179
|
+
if (options.tenant_id !== void 0) {
|
|
8180
|
+
const source = buildMetadataSourceConditions({ ...options, metadataPredicates: [] }, idx);
|
|
8181
|
+
const native = options.tenant_id === "default" ? " OR NOT EXISTS (SELECT 1 FROM source_identity si WHERE si.note_id = n.id)" : "";
|
|
8182
|
+
conditions.push(`(EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})${native})`);
|
|
8183
|
+
params.push(...source.params);
|
|
8184
|
+
idx = source.nextIdx;
|
|
8185
|
+
}
|
|
8186
|
+
for (const predicate of predicates) {
|
|
8187
|
+
if (predicate.path === "import_run_id") continue;
|
|
8188
|
+
const lhs = `(n.metadata -> '${predicate.path}')`;
|
|
8189
|
+
conditions.push(predicateSql(predicate, (value, op) => {
|
|
8190
|
+
if (value === null) return `jsonb_typeof(${lhs}) = 'null'`;
|
|
8191
|
+
const rhs = `$${idx++}::jsonb`;
|
|
8192
|
+
params.push(JSON.stringify(value));
|
|
8193
|
+
const type = typeof value;
|
|
8194
|
+
if (type === "string") {
|
|
8195
|
+
return `(jsonb_typeof(${lhs}) = 'string'
|
|
8196
|
+
AND public.metadata_search_order_key_v1(${lhs}) IS NULL
|
|
8197
|
+
AND public.metadata_search_text_key_v1(${lhs}) COLLATE "C" ${op} public.metadata_search_text_key_v1(${rhs}) COLLATE "C"
|
|
8198
|
+
AND (${lhs} #>> '{}') COLLATE "C" ${op} (${rhs} #>> '{}') COLLATE "C")`;
|
|
8199
|
+
}
|
|
8200
|
+
return `(jsonb_typeof(${lhs}) = '${type}'
|
|
8201
|
+
AND public.metadata_search_order_key_v1(${lhs}) ${op} public.metadata_search_order_key_v1(${rhs})
|
|
8202
|
+
AND ${lhs} ${op} ${rhs})`;
|
|
8203
|
+
}, `jsonb_typeof(${lhs}) IS NOT NULL`));
|
|
8204
|
+
}
|
|
8205
|
+
const runs = predicates.filter((p) => p.path === "import_run_id");
|
|
8206
|
+
if (runs.length) {
|
|
8207
|
+
const positive = runs.filter((p) => !(p.op === "exists" && p.value === false));
|
|
8208
|
+
for (const [selected, negated] of [[positive, false], [[], true]]) {
|
|
8209
|
+
if (negated ? !runs.some((p) => p.op === "exists" && p.value === false) : !positive.length) continue;
|
|
8210
|
+
const source = buildMetadataSourceConditions({ ...options, metadataPredicates: selected }, idx);
|
|
8211
|
+
conditions.push(`${negated ? "NOT " : ""}EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})`);
|
|
8212
|
+
params.push(...source.params);
|
|
8213
|
+
idx = source.nextIdx;
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
8216
|
+
return { conditions, joins, params, nextIdx: idx };
|
|
8217
|
+
}
|
|
8218
|
+
|
|
8219
|
+
// src/repositories/search-evidence-repository.ts
|
|
8220
|
+
function validateScope(scope) {
|
|
8221
|
+
if (!scope || typeof scope !== "object" || Array.isArray(scope) || ![Object.prototype, null].includes(Object.getPrototypeOf(scope)) || Object.keys(scope).some((key3) => !["tenant_id", "archive_id", "visibility", "metadataPredicates"].includes(key3))) {
|
|
8222
|
+
throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8223
|
+
}
|
|
8224
|
+
for (const key3 of ["tenant_id", "archive_id", "visibility"]) {
|
|
8225
|
+
const value = scope[key3];
|
|
8226
|
+
if (value === void 0 || key3 === "archive_id" && value === null) continue;
|
|
8227
|
+
if (typeof value !== "string" || value.length === 0 || value.includes("\0") || Array.from(value).some((char) => {
|
|
8228
|
+
const code = char.codePointAt(0);
|
|
8229
|
+
return code >= 55296 && code <= 57343;
|
|
8230
|
+
})) throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8231
|
+
}
|
|
8232
|
+
}
|
|
8233
|
+
async function resolveStoredSearchEvidence(db, value, scope = {}) {
|
|
8234
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
8235
|
+
validateScope(scope);
|
|
8236
|
+
const options = { ...scope, tenant_id: scope.tenant_id ?? "default" };
|
|
8237
|
+
const notes = buildNoteConditions(options, 5);
|
|
8238
|
+
const metadata2 = buildMetadataPredicateConditions(options, notes.nextIdx);
|
|
8239
|
+
const params = [
|
|
8240
|
+
locator.note_id,
|
|
8241
|
+
locator.unit.id,
|
|
8242
|
+
locator.unit.index,
|
|
8243
|
+
MAX_EVIDENCE_BYTES,
|
|
8244
|
+
...notes.params,
|
|
8245
|
+
...metadata2.params
|
|
8246
|
+
];
|
|
8247
|
+
const conditions = ["n.id = $1", ...notes.conditions, ...metadata2.conditions];
|
|
8248
|
+
let joins;
|
|
8249
|
+
let content;
|
|
8250
|
+
switch (locator.unit.kind) {
|
|
8251
|
+
case "current":
|
|
8252
|
+
joins = "JOIN note_revised_current c ON c.note_id = n.id";
|
|
8253
|
+
content = "c.content";
|
|
8254
|
+
conditions.push("n.id = $2", "$3::integer = 0");
|
|
8255
|
+
break;
|
|
8256
|
+
case "title":
|
|
8257
|
+
joins = "";
|
|
8258
|
+
content = "n.title";
|
|
8259
|
+
conditions.push("n.id = $2", "$3::integer = 0");
|
|
8260
|
+
break;
|
|
8261
|
+
case "embedding":
|
|
8262
|
+
joins = "JOIN embedding e ON e.note_id = n.id";
|
|
8263
|
+
content = "e.text";
|
|
8264
|
+
conditions.push("e.id = $2", "e.chunk_index = $3");
|
|
8265
|
+
break;
|
|
8266
|
+
case "attachment":
|
|
8267
|
+
joins = "JOIN attachment a ON a.note_id = n.id";
|
|
8268
|
+
content = "a.extracted_text";
|
|
8269
|
+
conditions.push("a.id = $2", "$3::integer = 0", "a.status = 'completed'", "a.deleted_at IS NULL");
|
|
8270
|
+
break;
|
|
8271
|
+
}
|
|
8272
|
+
if (locator.source) {
|
|
8273
|
+
const source = buildMetadataSourceConditions(options, metadata2.nextIdx);
|
|
8274
|
+
let idx = source.nextIdx;
|
|
8275
|
+
conditions.push(`EXISTS (SELECT 1 FROM source_identity si
|
|
8276
|
+
WHERE ${source.conditions.join(" AND ")}
|
|
8277
|
+
AND si.namespace = $${idx++} AND si.external_id_hash = $${idx++}
|
|
8278
|
+
AND si.import_run_id = $${idx++} AND si.source_schema_version = $${idx++})`);
|
|
8279
|
+
params.push(
|
|
8280
|
+
...source.params,
|
|
8281
|
+
locator.source.namespace,
|
|
8282
|
+
locator.source.external_id_hash,
|
|
8283
|
+
locator.source.import_run_id,
|
|
8284
|
+
locator.source.schema_version
|
|
8285
|
+
);
|
|
8286
|
+
}
|
|
8287
|
+
const result = await db.query(
|
|
8288
|
+
`SELECT CASE WHEN octet_length(${content}) <= $4
|
|
8289
|
+
THEN encode(convert_to(${content}, 'UTF8'), 'hex') ELSE NULL END AS content_hex
|
|
8290
|
+
FROM note n ${joins} ${metadata2.joins.join(" ")}
|
|
8291
|
+
WHERE ${conditions.join(" AND ")} LIMIT 1`,
|
|
8292
|
+
params
|
|
8293
|
+
);
|
|
8294
|
+
const row = result.rows[0];
|
|
8295
|
+
return resolveSearchEvidence(locator, row?.content_hex == null ? null : {
|
|
8296
|
+
note_id: locator.note_id,
|
|
8297
|
+
unit: locator.unit,
|
|
8298
|
+
content: new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(hexToBytes(row.content_hex)),
|
|
8299
|
+
...locator.source === void 0 ? {} : { source: locator.source }
|
|
8300
|
+
});
|
|
8301
|
+
}
|
|
8302
|
+
|
|
8303
|
+
// src/repositories/search-evidence-projection.ts
|
|
8304
|
+
init_geometry_buffer();
|
|
8305
|
+
|
|
8306
|
+
// src/search-evidence-set.ts
|
|
8307
|
+
init_geometry_buffer();
|
|
8308
|
+
|
|
8309
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-set.schema.json
|
|
8310
|
+
var evidence_set_schema_default = {
|
|
8311
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
8312
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-set.schema.json",
|
|
8313
|
+
title: "Candidate per-hit search evidence envelope",
|
|
8314
|
+
type: "object",
|
|
8315
|
+
additionalProperties: false,
|
|
8316
|
+
required: ["version", "locators", "omissions"],
|
|
8317
|
+
properties: {
|
|
8318
|
+
version: { const: "1.0.0" },
|
|
8319
|
+
locators: {
|
|
8320
|
+
type: "array",
|
|
8321
|
+
maxItems: 64,
|
|
8322
|
+
uniqueItems: true,
|
|
8323
|
+
items: { $ref: "evidence-locator.schema.json" }
|
|
8324
|
+
},
|
|
8325
|
+
omissions: {
|
|
8326
|
+
type: "array",
|
|
8327
|
+
maxItems: 2,
|
|
8328
|
+
uniqueItems: true,
|
|
8329
|
+
items: { enum: ["unavailable-unit", "locator-limit"] }
|
|
8330
|
+
}
|
|
8331
|
+
},
|
|
8332
|
+
if: { properties: { locators: { type: "array", maxItems: 0 } } },
|
|
8333
|
+
then: { properties: { omissions: { type: "array", minItems: 1 } } }
|
|
8334
|
+
};
|
|
8335
|
+
|
|
8336
|
+
// src/search-evidence-set.ts
|
|
8337
|
+
var MAX_SEARCH_LOCATORS = 64;
|
|
8338
|
+
var EVIDENCE_OMISSIONS = ["unavailable-unit", "locator-limit"];
|
|
8339
|
+
var validate = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addSchema(evidence_locator_schema_default).compile(evidence_set_schema_default);
|
|
8340
|
+
var invalid2 = () => new Error("SEARCH_EVIDENCE_INVALID");
|
|
8341
|
+
var priorities = { embedding: 0, title: 1, current: 2, attachment: 3 };
|
|
8342
|
+
function scalarCompare(left, right) {
|
|
8343
|
+
const a = Array.from(left, (char) => char.codePointAt(0));
|
|
8344
|
+
const b = Array.from(right, (char) => char.codePointAt(0));
|
|
8345
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
8346
|
+
return a.length - b.length;
|
|
8347
|
+
}
|
|
8348
|
+
function key(locator) {
|
|
8349
|
+
return [
|
|
8350
|
+
priorities[locator.unit.kind],
|
|
8351
|
+
locator.unit.id,
|
|
8352
|
+
locator.unit.index,
|
|
8353
|
+
locator.content_digest,
|
|
8354
|
+
locator.span.start,
|
|
8355
|
+
locator.span.end,
|
|
8356
|
+
locator.source ? 1 : 0,
|
|
8357
|
+
locator.source?.namespace ?? "",
|
|
8358
|
+
locator.source?.external_id_hash ?? "",
|
|
8359
|
+
locator.source?.import_run_id ?? "",
|
|
8360
|
+
locator.source?.schema_version ?? ""
|
|
8361
|
+
];
|
|
8362
|
+
}
|
|
8363
|
+
function compareSearchEvidence(left, right) {
|
|
8364
|
+
const a = key(left), b = key(right);
|
|
8365
|
+
for (let i = 0; i < a.length; i++) {
|
|
8366
|
+
const cmp = typeof a[i] === "number" ? a[i] - b[i] : scalarCompare(a[i], b[i]);
|
|
8367
|
+
if (cmp !== 0) return cmp;
|
|
8368
|
+
}
|
|
8369
|
+
return 0;
|
|
8370
|
+
}
|
|
8371
|
+
function parseSearchEvidenceSet(value, noteId) {
|
|
8372
|
+
if (!validate(value)) throw invalid2();
|
|
8373
|
+
const locators = value.locators.map(parseSearchEvidenceLocator);
|
|
8374
|
+
if (locators.some((locator, i) => locator.note_id !== noteId || i > 0 && compareSearchEvidence(locators[i - 1], locator) >= 0)) throw invalid2();
|
|
8375
|
+
if (value.omissions.some((reason, i) => i > 0 && EVIDENCE_OMISSIONS.indexOf(value.omissions[i - 1]) >= EVIDENCE_OMISSIONS.indexOf(reason))) throw invalid2();
|
|
8376
|
+
return Object.freeze({ version: "1.0.0", locators: Object.freeze(locators), omissions: Object.freeze([...value.omissions]) });
|
|
8377
|
+
}
|
|
8378
|
+
function createSearchEvidenceSet(noteId, values, omissions = []) {
|
|
8379
|
+
const parsed = values.map(parseSearchEvidenceLocator);
|
|
8380
|
+
if (parsed.some((locator) => locator.note_id !== noteId) || omissions.some((reason) => !EVIDENCE_OMISSIONS.includes(reason))) throw invalid2();
|
|
8381
|
+
const locators = parsed.sort(compareSearchEvidence).filter((locator, i, all) => i === 0 || compareSearchEvidence(all[i - 1], locator) !== 0);
|
|
8382
|
+
const reasons = new Set(omissions);
|
|
8383
|
+
if (locators.length > MAX_SEARCH_LOCATORS) reasons.add("locator-limit");
|
|
8384
|
+
if (locators.length === 0) reasons.add("unavailable-unit");
|
|
8385
|
+
return parseSearchEvidenceSet({
|
|
8386
|
+
version: "1.0.0",
|
|
8387
|
+
locators: locators.slice(0, MAX_SEARCH_LOCATORS),
|
|
8388
|
+
omissions: EVIDENCE_OMISSIONS.filter((reason) => reasons.has(reason))
|
|
8389
|
+
}, noteId);
|
|
8390
|
+
}
|
|
8391
|
+
function mergeSearchEvidenceSets(noteId, sets) {
|
|
8392
|
+
const checked2 = sets.map((set) => parseSearchEvidenceSet(set, noteId));
|
|
8393
|
+
return createSearchEvidenceSet(noteId, checked2.flatMap((set) => [...set.locators]), checked2.flatMap((set) => [...set.omissions]));
|
|
8394
|
+
}
|
|
8395
|
+
|
|
8396
|
+
// src/repositories/search-evidence-projection.ts
|
|
8397
|
+
function buildSearchEvidenceProjection(options, startIdx, match) {
|
|
8398
|
+
const source = buildMetadataSourceConditions(options, startIdx);
|
|
8399
|
+
const scope = buildMetadataPredicateConditions({ tenant_id: options.tenant_id ?? "default", archive_id: options.archive_id }, source.nextIdx);
|
|
8400
|
+
const units = [];
|
|
8401
|
+
if (match.lexical) {
|
|
8402
|
+
const query = `${match.lexical.fn}('english', $${match.lexical.parameter})`;
|
|
8403
|
+
units.push(`SELECT 1 AS priority, 'title'::text AS kind, n.id AS id, 0 AS index, n.title AS content
|
|
8404
|
+
WHERE to_tsvector('english', n.title) @@ ${query}`);
|
|
8405
|
+
units.push(`SELECT 2, 'current', n.id, 0, c.content
|
|
8406
|
+
WHERE to_tsvector('english', c.content) @@ ${query}`);
|
|
8407
|
+
units.push(`SELECT 3, 'attachment', a.id, 0, a.extracted_text FROM attachment a
|
|
8408
|
+
WHERE a.note_id = n.id AND a.deleted_at IS NULL AND a.status = 'completed'
|
|
8409
|
+
AND to_tsvector('english', a.extracted_text) @@ ${query}`);
|
|
8410
|
+
}
|
|
8411
|
+
if (match.embedding) units.push("SELECT 0, 'embedding'::text, e.id, e.chunk_index, NULLIF(e.text, '')");
|
|
8412
|
+
if (units.length === 0) throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8413
|
+
return {
|
|
8414
|
+
params: [...source.params, ...scope.params],
|
|
8415
|
+
nextIdx: scope.nextIdx,
|
|
8416
|
+
sql: `(WITH units(priority, kind, id, index, content) AS (${units.join(" UNION ALL ")}),
|
|
8417
|
+
sources AS (
|
|
8418
|
+
SELECT DISTINCT si.namespace COLLATE "C" AS namespace, si.external_id_hash COLLATE "C" AS external_id_hash,
|
|
8419
|
+
si.import_run_id COLLATE "C" AS import_run_id, si.source_schema_version COLLATE "C" AS source_schema_version
|
|
8420
|
+
FROM source_identity si WHERE ${source.conditions.join(" AND ")}
|
|
8421
|
+
ORDER BY si.namespace COLLATE "C", si.external_id_hash COLLATE "C",
|
|
8422
|
+
si.import_run_id COLLATE "C", si.source_schema_version COLLATE "C"
|
|
8423
|
+
LIMIT ${MAX_SEARCH_LOCATORS + 1}
|
|
8424
|
+
), candidates AS MATERIALIZED (
|
|
8425
|
+
SELECT u.*, s.namespace, s.external_id_hash, s.import_run_id, s.source_schema_version
|
|
8426
|
+
FROM units u LEFT JOIN sources s ON true
|
|
8427
|
+
ORDER BY u.priority, u.id COLLATE "C", u.index, s.namespace COLLATE "C",
|
|
8428
|
+
s.external_id_hash COLLATE "C", s.import_run_id COLLATE "C", s.source_schema_version COLLATE "C"
|
|
8429
|
+
LIMIT ${MAX_SEARCH_LOCATORS + 1}
|
|
8430
|
+
), bound AS (
|
|
8431
|
+
SELECT CASE WHEN ${scope.conditions.join(" AND ")}
|
|
8432
|
+
AND char_length(n.id) BETWEEN 1 AND 200 AND char_length(id) BETWEEN 1 AND 200
|
|
8433
|
+
AND index BETWEEN 0 AND 2147483647 AND octet_length(content) <= ${MAX_EVIDENCE_BYTES}
|
|
8434
|
+
AND (namespace IS NULL OR (char_length(namespace) BETWEEN 1 AND 200
|
|
8435
|
+
AND external_id_hash ~ '^sha256:[a-f0-9]{64}$'
|
|
8436
|
+
AND char_length(import_run_id) BETWEEN 1 AND 200
|
|
8437
|
+
AND char_length(source_schema_version) BETWEEN 1 AND 200))
|
|
8438
|
+
THEN jsonb_build_object('version', '1.0.0', 'note_id', n.id,
|
|
8439
|
+
'unit', jsonb_build_object('kind', kind, 'id', id, 'index', index),
|
|
8440
|
+
'content_digest', 'sha256:' || encode(sha256(convert_to(content, 'UTF8')), 'hex'),
|
|
8441
|
+
'span', jsonb_build_object('unit', 'utf8-bytes', 'start', 0, 'end', octet_length(content)))
|
|
8442
|
+
|| CASE WHEN namespace IS NULL THEN '{}'::jsonb ELSE jsonb_build_object('source',
|
|
8443
|
+
jsonb_build_object('namespace', namespace, 'external_id_hash', external_id_hash,
|
|
8444
|
+
'import_run_id', import_run_id, 'schema_version', source_schema_version)) END
|
|
8445
|
+
ELSE NULL END AS locator FROM candidates
|
|
8446
|
+
) SELECT jsonb_build_object('locators', coalesce(jsonb_agg(locator), '[]'::jsonb),
|
|
8447
|
+
'limited', count(*) > ${MAX_SEARCH_LOCATORS}) FROM bound)`
|
|
8448
|
+
};
|
|
8449
|
+
}
|
|
8450
|
+
function projectedSearchEvidence(noteId, value) {
|
|
8451
|
+
return createSearchEvidenceSet(noteId, value.locators.filter((locator) => locator !== null), [
|
|
8452
|
+
...value.locators.some((locator) => locator === null) ? ["unavailable-unit"] : [],
|
|
8453
|
+
...value.limited ? ["locator-limit"] : []
|
|
8454
|
+
]);
|
|
8455
|
+
}
|
|
8456
|
+
|
|
7613
8457
|
// src/repositories/embedding-sets-repository.ts
|
|
7614
8458
|
init_geometry_buffer();
|
|
7615
8459
|
var ATTACHMENT_TEXT_JOIN = `
|
|
@@ -8189,91 +9033,6 @@ var EmbeddingSetsRepository = class {
|
|
|
8189
9033
|
}
|
|
8190
9034
|
};
|
|
8191
9035
|
|
|
8192
|
-
// src/repositories/metadata-predicates.ts
|
|
8193
|
-
init_geometry_buffer();
|
|
8194
|
-
var REGISTERED_METADATA_PATHS = [
|
|
8195
|
-
"provider",
|
|
8196
|
-
"model",
|
|
8197
|
-
"role",
|
|
8198
|
-
"event_kind",
|
|
8199
|
-
"sensitivity",
|
|
8200
|
-
"import_run_id"
|
|
8201
|
-
];
|
|
8202
|
-
var REGISTERED_SET = new Set(REGISTERED_METADATA_PATHS);
|
|
8203
|
-
var MAX_PREDICATES = 8;
|
|
8204
|
-
var MAX_IN_VALUES = 32;
|
|
8205
|
-
var MAX_VALUE_LENGTH = 256;
|
|
8206
|
-
function assertRegisteredPath(path) {
|
|
8207
|
-
if (!REGISTERED_SET.has(path) || path.includes(".") || path.includes("/")) {
|
|
8208
|
-
throw new Error(`Unsupported metadata predicate path: ${path}`);
|
|
8209
|
-
}
|
|
8210
|
-
}
|
|
8211
|
-
function assertBoundedValue(value) {
|
|
8212
|
-
if (typeof value === "string" && value.length > MAX_VALUE_LENGTH) {
|
|
8213
|
-
throw new Error("Metadata predicate value exceeds the 256 character bound");
|
|
8214
|
-
}
|
|
8215
|
-
}
|
|
8216
|
-
function jsonAccessor(path) {
|
|
8217
|
-
if (path === "import_run_id") return "si.import_run_id";
|
|
8218
|
-
return `n.metadata ->> '${path}'`;
|
|
8219
|
-
}
|
|
8220
|
-
function buildMetadataPredicateConditions(options, startIdx) {
|
|
8221
|
-
const predicates = options.metadataPredicates ?? [];
|
|
8222
|
-
if (predicates.length > MAX_PREDICATES) {
|
|
8223
|
-
throw new Error(`Metadata predicate count exceeds the ${MAX_PREDICATES} predicate bound`);
|
|
8224
|
-
}
|
|
8225
|
-
const conditions = [];
|
|
8226
|
-
const params = [];
|
|
8227
|
-
const joins = [];
|
|
8228
|
-
let idx = startIdx;
|
|
8229
|
-
let needsSourceJoin = options.tenant_id !== void 0 || options.archive_id !== void 0;
|
|
8230
|
-
if (options.tenant_id !== void 0) {
|
|
8231
|
-
conditions.push(`COALESCE(si.tenant_id, 'default') = $${idx++}`);
|
|
8232
|
-
params.push(options.tenant_id);
|
|
8233
|
-
}
|
|
8234
|
-
if (options.archive_id !== void 0) {
|
|
8235
|
-
conditions.push(`si.archive_id IS NOT DISTINCT FROM $${idx++}`);
|
|
8236
|
-
params.push(options.archive_id);
|
|
8237
|
-
}
|
|
8238
|
-
for (const predicate of predicates) {
|
|
8239
|
-
assertRegisteredPath(predicate.path);
|
|
8240
|
-
const lhs = jsonAccessor(predicate.path);
|
|
8241
|
-
if (predicate.path === "import_run_id") needsSourceJoin = true;
|
|
8242
|
-
if (predicate.op === "eq") {
|
|
8243
|
-
assertBoundedValue(predicate.value);
|
|
8244
|
-
conditions.push(`${lhs} IS NOT DISTINCT FROM $${idx++}`);
|
|
8245
|
-
params.push(predicate.value == null ? null : String(predicate.value));
|
|
8246
|
-
} else if (predicate.op === "in") {
|
|
8247
|
-
if (predicate.value.length > MAX_IN_VALUES) {
|
|
8248
|
-
throw new Error(`Metadata predicate membership exceeds the ${MAX_IN_VALUES} value bound`);
|
|
8249
|
-
}
|
|
8250
|
-
for (const value of predicate.value) assertBoundedValue(value);
|
|
8251
|
-
conditions.push(`${lhs} = ANY($${idx++})`);
|
|
8252
|
-
params.push(predicate.value.map((value) => value == null ? null : String(value)));
|
|
8253
|
-
} else if (predicate.op === "range") {
|
|
8254
|
-
if (predicate.gte === void 0 && predicate.lte === void 0) {
|
|
8255
|
-
throw new Error("Metadata range predicate requires gte or lte");
|
|
8256
|
-
}
|
|
8257
|
-
if (predicate.gte !== void 0) {
|
|
8258
|
-
assertBoundedValue(predicate.gte);
|
|
8259
|
-
conditions.push(`${lhs} >= $${idx++}`);
|
|
8260
|
-
params.push(String(predicate.gte));
|
|
8261
|
-
}
|
|
8262
|
-
if (predicate.lte !== void 0) {
|
|
8263
|
-
assertBoundedValue(predicate.lte);
|
|
8264
|
-
conditions.push(`${lhs} <= $${idx++}`);
|
|
8265
|
-
params.push(String(predicate.lte));
|
|
8266
|
-
}
|
|
8267
|
-
} else {
|
|
8268
|
-
conditions.push(predicate.value === false ? `${lhs} IS NULL` : `${lhs} IS NOT NULL`);
|
|
8269
|
-
}
|
|
8270
|
-
}
|
|
8271
|
-
if (needsSourceJoin) {
|
|
8272
|
-
joins.push("LEFT JOIN source_identity si ON si.note_id = n.id");
|
|
8273
|
-
}
|
|
8274
|
-
return { conditions, joins, params, nextIdx: idx };
|
|
8275
|
-
}
|
|
8276
|
-
|
|
8277
9036
|
// src/repositories/search-repository.ts
|
|
8278
9037
|
var ATTACHMENT_TEXT_JOIN2 = `
|
|
8279
9038
|
LEFT JOIN (
|
|
@@ -8295,6 +9054,10 @@ var SearchRepository = class {
|
|
|
8295
9054
|
this.db = db;
|
|
8296
9055
|
this.semanticAvailable = semanticAvailable;
|
|
8297
9056
|
}
|
|
9057
|
+
/** Candidate citation resolution with fresh local scope and content checks. */
|
|
9058
|
+
async resolveEvidence(locator, scope = {}) {
|
|
9059
|
+
return resolveStoredSearchEvidence(this.db, locator, scope);
|
|
9060
|
+
}
|
|
8298
9061
|
tsqueryFn(query) {
|
|
8299
9062
|
return query.includes('"') ? "phraseto_tsquery" : "plainto_tsquery";
|
|
8300
9063
|
}
|
|
@@ -8304,7 +9067,7 @@ var SearchRepository = class {
|
|
|
8304
9067
|
const setFilter = embeddingSetId ? " AND embedding_set_id = $2" : "";
|
|
8305
9068
|
if (embeddingSetId) params.push(embeddingSetId);
|
|
8306
9069
|
const result = await this.db.query(
|
|
8307
|
-
"SELECT note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
|
|
9070
|
+
"SELECT to_jsonb(note_id) AS note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
|
|
8308
9071
|
params
|
|
8309
9072
|
);
|
|
8310
9073
|
return new Set(result.rows.map((r) => r.note_id));
|
|
@@ -8348,15 +9111,17 @@ var SearchRepository = class {
|
|
|
8348
9111
|
attachEmbeddingStatus(results, embeddingSet) {
|
|
8349
9112
|
return results.map((r) => ({ ...r, has_embedding: embeddingSet.has(r.id) }));
|
|
8350
9113
|
}
|
|
8351
|
-
async fetchLocatorMap(noteIds,
|
|
9114
|
+
async fetchLocatorMap(noteIds, options) {
|
|
8352
9115
|
const locators = /* @__PURE__ */ new Map();
|
|
8353
9116
|
if (noteIds.length === 0) return locators;
|
|
9117
|
+
const metadataPaths = this.metadataPaths(options);
|
|
9118
|
+
const source = buildMetadataSourceConditions(options, 2);
|
|
8354
9119
|
const result = await this.db.query(
|
|
8355
|
-
`SELECT note_id, namespace, external_id_hash, import_run_id, source_schema_version
|
|
8356
|
-
FROM source_identity
|
|
8357
|
-
WHERE
|
|
8358
|
-
ORDER BY created_at ASC`,
|
|
8359
|
-
[noteIds]
|
|
9120
|
+
`SELECT to_jsonb(si.note_id) AS note_id, si.namespace, si.external_id_hash, si.import_run_id, si.source_schema_version
|
|
9121
|
+
FROM source_identity si JOIN note n ON n.id = si.note_id
|
|
9122
|
+
WHERE n.id = ANY($1) AND ${source.conditions.join(" AND ")}
|
|
9123
|
+
ORDER BY si.created_at ASC, si.id ASC`,
|
|
9124
|
+
[noteIds, ...source.params]
|
|
8360
9125
|
);
|
|
8361
9126
|
for (const row of result.rows) {
|
|
8362
9127
|
const existing = locators.get(row.note_id) ?? [];
|
|
@@ -8384,6 +9149,7 @@ var SearchRepository = class {
|
|
|
8384
9149
|
return [...new Set((options.metadataPredicates ?? []).map((predicate) => predicate.path))];
|
|
8385
9150
|
}
|
|
8386
9151
|
async search(query, options = {}, queryEmbedding) {
|
|
9152
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
8387
9153
|
const { limit = 20, offset = 0 } = options;
|
|
8388
9154
|
const mode = options.mode ?? "auto";
|
|
8389
9155
|
if (mode === "text") {
|
|
@@ -8429,9 +9195,11 @@ var SearchRepository = class {
|
|
|
8429
9195
|
allParams
|
|
8430
9196
|
);
|
|
8431
9197
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
8432
|
-
const
|
|
9198
|
+
const evidence = buildSearchEvidenceProjection(options, paramIdx, { lexical: { fn: tsqFn, parameter: 1 } });
|
|
9199
|
+
paramIdx = evidence.nextIdx;
|
|
9200
|
+
const searchParams = [...allParams, ...evidence.params, limit, offset];
|
|
8433
9201
|
const result = await this.db.query(
|
|
8434
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9202
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at, ${evidence.sql} AS evidence_projection,
|
|
8435
9203
|
ts_rank(
|
|
8436
9204
|
setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
|
|
8437
9205
|
${tsqFn}('english', $1)
|
|
@@ -8459,7 +9227,7 @@ var SearchRepository = class {
|
|
|
8459
9227
|
let facets;
|
|
8460
9228
|
if (options.include_facets) {
|
|
8461
9229
|
const idsResult = await this.db.query(
|
|
8462
|
-
`SELECT n.id FROM note n
|
|
9230
|
+
`SELECT to_jsonb(n.id) AS id FROM note n
|
|
8463
9231
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
8464
9232
|
${metadata2.joins.join("\n")}
|
|
8465
9233
|
${ATTACHMENT_TEXT_JOIN2}
|
|
@@ -8468,7 +9236,7 @@ var SearchRepository = class {
|
|
|
8468
9236
|
);
|
|
8469
9237
|
facets = await this.fetchFacets(idsResult.rows.map((r) => r.id));
|
|
8470
9238
|
}
|
|
8471
|
-
const locatorMap = await this.fetchLocatorMap(resultIds,
|
|
9239
|
+
const locatorMap = await this.fetchLocatorMap(resultIds, options);
|
|
8472
9240
|
const baseResults = result.rows.map((r) => ({
|
|
8473
9241
|
id: r.id,
|
|
8474
9242
|
title: r.title,
|
|
@@ -8477,7 +9245,8 @@ var SearchRepository = class {
|
|
|
8477
9245
|
created_at: r.created_at,
|
|
8478
9246
|
updated_at: r.updated_at,
|
|
8479
9247
|
tags: tagMap.get(r.id) ?? [],
|
|
8480
|
-
locators: locatorMap.get(r.id) ?? []
|
|
9248
|
+
locators: locatorMap.get(r.id) ?? [],
|
|
9249
|
+
evidence: projectedSearchEvidence(r.id, r.evidence_projection)
|
|
8481
9250
|
}));
|
|
8482
9251
|
return {
|
|
8483
9252
|
results: this.attachEmbeddingStatus(baseResults, embeddingSet),
|
|
@@ -8491,6 +9260,7 @@ var SearchRepository = class {
|
|
|
8491
9260
|
};
|
|
8492
9261
|
}
|
|
8493
9262
|
async semanticSearch(queryEmbedding, options = {}) {
|
|
9263
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
8494
9264
|
const { limit = 20, offset = 0 } = options;
|
|
8495
9265
|
const vector = vectorColumn(queryEmbedding);
|
|
8496
9266
|
const vectorStr = `[${queryEmbedding.join(",")}]`;
|
|
@@ -8512,11 +9282,14 @@ var SearchRepository = class {
|
|
|
8512
9282
|
params
|
|
8513
9283
|
);
|
|
8514
9284
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
9285
|
+
const evidence = buildSearchEvidenceProjection(options, paramIdx, { embedding: true });
|
|
9286
|
+
paramIdx = evidence.nextIdx;
|
|
8515
9287
|
const vecIdx = paramIdx++;
|
|
8516
9288
|
const limIdx = paramIdx++;
|
|
8517
9289
|
const offIdx = paramIdx++;
|
|
8518
9290
|
const result = await this.db.query(
|
|
8519
|
-
`SELECT * FROM (SELECT DISTINCT ON (n.id) n.id, n.title, n.created_at, n.updated_at,
|
|
9291
|
+
`SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
9292
|
+
${evidence.sql} AS evidence_projection,
|
|
8520
9293
|
(${vector} <=> $${vecIdx}::vector) as distance,
|
|
8521
9294
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
8522
9295
|
FROM embedding e
|
|
@@ -8528,11 +9301,11 @@ var SearchRepository = class {
|
|
|
8528
9301
|
ORDER BY n.id, ${vector} <=> $${vecIdx}::vector ASC, e.id) AS best_chunks
|
|
8529
9302
|
ORDER BY distance ASC, id
|
|
8530
9303
|
LIMIT $${limIdx} OFFSET $${offIdx}`,
|
|
8531
|
-
[...params, vectorStr, limit, offset]
|
|
9304
|
+
[...params, ...evidence.params, vectorStr, limit, offset]
|
|
8532
9305
|
);
|
|
8533
9306
|
const tagMap = await this.fetchTagMap(result.rows.map((r) => r.id));
|
|
8534
9307
|
const facets = options.include_facets ? await this.fetchFacets((await this.db.query(
|
|
8535
|
-
`SELECT n.id
|
|
9308
|
+
`SELECT to_jsonb(n.id) AS id
|
|
8536
9309
|
FROM embedding e
|
|
8537
9310
|
JOIN note n ON n.id = e.note_id
|
|
8538
9311
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8540,7 +9313,7 @@ var SearchRepository = class {
|
|
|
8540
9313
|
WHERE ${where}`,
|
|
8541
9314
|
params
|
|
8542
9315
|
)).rows.map((r) => r.id)) : void 0;
|
|
8543
|
-
const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id),
|
|
9316
|
+
const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id), options);
|
|
8544
9317
|
return {
|
|
8545
9318
|
results: result.rows.map((r) => ({
|
|
8546
9319
|
id: r.id,
|
|
@@ -8551,7 +9324,8 @@ var SearchRepository = class {
|
|
|
8551
9324
|
updated_at: r.updated_at,
|
|
8552
9325
|
tags: tagMap.get(r.id) ?? [],
|
|
8553
9326
|
has_embedding: true,
|
|
8554
|
-
locators: locatorMap.get(r.id) ?? []
|
|
9327
|
+
locators: locatorMap.get(r.id) ?? [],
|
|
9328
|
+
evidence: projectedSearchEvidence(r.id, r.evidence_projection)
|
|
8555
9329
|
})),
|
|
8556
9330
|
total,
|
|
8557
9331
|
query: "",
|
|
@@ -8563,6 +9337,7 @@ var SearchRepository = class {
|
|
|
8563
9337
|
};
|
|
8564
9338
|
}
|
|
8565
9339
|
async hybridSearch(query, queryEmbedding, options = {}) {
|
|
9340
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
8566
9341
|
const { limit = 20, offset = 0 } = options;
|
|
8567
9342
|
const vectorStr = `[${queryEmbedding.join(",")}]`;
|
|
8568
9343
|
const k = 60;
|
|
@@ -8577,11 +9352,12 @@ var SearchRepository = class {
|
|
|
8577
9352
|
${COMBINED_TEXT_VECTOR_SQL2} @@ ${tsqFn}('english', $1))`
|
|
8578
9353
|
];
|
|
8579
9354
|
textCond.params.push(...textMeta.params);
|
|
8580
|
-
this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
|
|
9355
|
+
const textNextIdx = this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
|
|
8581
9356
|
const textWhere = textConditions.join(" AND ");
|
|
8582
|
-
const
|
|
9357
|
+
const textEvidence = buildSearchEvidenceProjection(options, textNextIdx, { lexical: { fn: tsqFn, parameter: 1 } });
|
|
9358
|
+
const textParams = [query, ...textCond.params, ...textEvidence.params];
|
|
8583
9359
|
const textResult = await this.db.query(
|
|
8584
|
-
`SELECT n.id,
|
|
9360
|
+
`SELECT to_jsonb(n.id) AS id, ${textEvidence.sql} AS evidence_projection,
|
|
8585
9361
|
ts_rank(
|
|
8586
9362
|
setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
|
|
8587
9363
|
${tsqFn}('english', $1)
|
|
@@ -8603,9 +9379,11 @@ var SearchRepository = class {
|
|
|
8603
9379
|
const vector = vectorColumn(queryEmbedding);
|
|
8604
9380
|
vecCond.conditions.push(`vector_dims(e.vector) = ${queryEmbedding.length}`);
|
|
8605
9381
|
const vecWhere = vecCond.conditions.join(" AND ");
|
|
8606
|
-
const
|
|
9382
|
+
const vectorEvidence = buildSearchEvidenceProjection(options, vecCond.nextIdx, { embedding: true });
|
|
9383
|
+
const vecVecIdx = vectorEvidence.nextIdx;
|
|
8607
9384
|
const vectorResult = await this.db.query(
|
|
8608
|
-
`SELECT * FROM (SELECT DISTINCT ON (n.id) n.id,
|
|
9385
|
+
`SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, ${vectorEvidence.sql} AS evidence_projection,
|
|
9386
|
+
(${vector} <=> $${vecVecIdx}::vector) as distance
|
|
8609
9387
|
FROM embedding e
|
|
8610
9388
|
JOIN note n ON n.id = e.note_id
|
|
8611
9389
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8614,9 +9392,15 @@ var SearchRepository = class {
|
|
|
8614
9392
|
ORDER BY n.id, ${vector} <=> $${vecVecIdx}::vector ASC, e.id) AS best_chunks
|
|
8615
9393
|
ORDER BY distance ASC, id
|
|
8616
9394
|
LIMIT 100`,
|
|
8617
|
-
[...vecCond.params, vectorStr]
|
|
9395
|
+
[...vecCond.params, ...vectorEvidence.params, vectorStr]
|
|
8618
9396
|
);
|
|
8619
9397
|
const rrfScores = /* @__PURE__ */ new Map();
|
|
9398
|
+
const evidenceMap = /* @__PURE__ */ new Map();
|
|
9399
|
+
for (const row of [...textResult.rows, ...vectorResult.rows]) {
|
|
9400
|
+
const existing = evidenceMap.get(row.id) ?? [];
|
|
9401
|
+
existing.push(projectedSearchEvidence(row.id, row.evidence_projection));
|
|
9402
|
+
evidenceMap.set(row.id, existing);
|
|
9403
|
+
}
|
|
8620
9404
|
textResult.rows.forEach((row, idx) => {
|
|
8621
9405
|
rrfScores.set(row.id, (rrfScores.get(row.id) ?? 0) + 1 / (k + idx + 1));
|
|
8622
9406
|
});
|
|
@@ -8629,21 +9413,24 @@ var SearchRepository = class {
|
|
|
8629
9413
|
if (pageIds.length === 0) {
|
|
8630
9414
|
return { results: [], total, query, mode: "hybrid", semantic_available: this.semanticAvailable, limit, offset };
|
|
8631
9415
|
}
|
|
9416
|
+
const displayConditions = buildNoteConditions(options, 2);
|
|
9417
|
+
const displayMetadata = buildMetadataPredicateConditions(options, displayConditions.nextIdx);
|
|
8632
9418
|
const noteResult = await this.db.query(
|
|
8633
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9419
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
8634
9420
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
8635
9421
|
FROM note n
|
|
8636
9422
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
8637
9423
|
${ATTACHMENT_TEXT_JOIN2}
|
|
8638
|
-
|
|
8639
|
-
|
|
9424
|
+
${displayMetadata.joins.join("\n")}
|
|
9425
|
+
WHERE n.id = ANY($1) AND ${[...displayConditions.conditions, ...displayMetadata.conditions].join(" AND ")}`,
|
|
9426
|
+
[pageIds, ...displayConditions.params, ...displayMetadata.params]
|
|
8640
9427
|
);
|
|
8641
9428
|
const noteMap = new Map(noteResult.rows.map((r) => [r.id, r]));
|
|
8642
9429
|
const [tagMap, embeddingSet] = await Promise.all([
|
|
8643
9430
|
this.fetchTagMap(pageIds),
|
|
8644
9431
|
this.fetchEmbeddingStatus(pageIds, resolvedEmbeddingSet, options.embeddingSetId)
|
|
8645
9432
|
]);
|
|
8646
|
-
const locatorMap = await this.fetchLocatorMap(pageIds,
|
|
9433
|
+
const locatorMap = await this.fetchLocatorMap(pageIds, options);
|
|
8647
9434
|
const facets = options.include_facets ? await this.fetchFacets(sortedIds) : void 0;
|
|
8648
9435
|
return {
|
|
8649
9436
|
results: pageIds.map((id) => {
|
|
@@ -8658,7 +9445,8 @@ var SearchRepository = class {
|
|
|
8658
9445
|
updated_at: r.updated_at,
|
|
8659
9446
|
tags: tagMap.get(id) ?? [],
|
|
8660
9447
|
has_embedding: embeddingSet.has(id),
|
|
8661
|
-
locators: locatorMap.get(id) ?? []
|
|
9448
|
+
locators: locatorMap.get(id) ?? [],
|
|
9449
|
+
evidence: mergeSearchEvidenceSets(id, evidenceMap.get(id) ?? [])
|
|
8662
9450
|
};
|
|
8663
9451
|
}).filter((r) => r !== null),
|
|
8664
9452
|
total,
|
|
@@ -8690,7 +9478,7 @@ var SearchRepository = class {
|
|
|
8690
9478
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
8691
9479
|
const listParams = [...params, limit, offset];
|
|
8692
9480
|
const result = await this.db.query(
|
|
8693
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9481
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
8694
9482
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
8695
9483
|
FROM note n
|
|
8696
9484
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8703,7 +9491,7 @@ var SearchRepository = class {
|
|
|
8703
9491
|
);
|
|
8704
9492
|
const resultIds = result.rows.map((r) => r.id);
|
|
8705
9493
|
const embeddingSet = await this.fetchEmbeddingStatus(resultIds, resolvedEmbeddingSet, options.embeddingSetId);
|
|
8706
|
-
const locatorMap = await this.fetchLocatorMap(resultIds,
|
|
9494
|
+
const locatorMap = await this.fetchLocatorMap(resultIds, options);
|
|
8707
9495
|
return {
|
|
8708
9496
|
results: result.rows.map((r) => ({
|
|
8709
9497
|
id: r.id,
|
|
@@ -8748,7 +9536,7 @@ var SearchRepository = class {
|
|
|
8748
9536
|
const tagMap = /* @__PURE__ */ new Map();
|
|
8749
9537
|
if (noteIds.length === 0) return tagMap;
|
|
8750
9538
|
const tagsResult = await this.db.query(
|
|
8751
|
-
`SELECT note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
|
|
9539
|
+
`SELECT to_jsonb(note_id) AS note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
|
|
8752
9540
|
[noteIds]
|
|
8753
9541
|
);
|
|
8754
9542
|
for (const row of tagsResult.rows) {
|
|
@@ -8992,7 +9780,7 @@ init_geometry_buffer();
|
|
|
8992
9780
|
// src/shard/full-v1-references.ts
|
|
8993
9781
|
init_geometry_buffer();
|
|
8994
9782
|
var uuid2 = (value) => typeof value === "string" ? value.toLowerCase() : value;
|
|
8995
|
-
var
|
|
9783
|
+
var key2 = (...values) => JSON.stringify(values);
|
|
8996
9784
|
var present = (value) => value !== null && value !== void 0;
|
|
8997
9785
|
function fullV1ReferenceErrors(records) {
|
|
8998
9786
|
const errors = [];
|
|
@@ -9050,7 +9838,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9050
9838
|
const id = uuid2(attachment.id);
|
|
9051
9839
|
check(!attachmentIds.has(id), "notes", index, "duplicate attachment identity");
|
|
9052
9840
|
attachmentIds.add(id);
|
|
9053
|
-
const declaration =
|
|
9841
|
+
const declaration = key2(attachment.bytes, attachment.mime);
|
|
9054
9842
|
check(
|
|
9055
9843
|
!digests.has(attachment.checksum) || digests.get(attachment.checksum) === declaration,
|
|
9056
9844
|
"notes",
|
|
@@ -9076,7 +9864,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9076
9864
|
}
|
|
9077
9865
|
});
|
|
9078
9866
|
ids2("note_original_history");
|
|
9079
|
-
unique2("note_original_history", (row) =>
|
|
9867
|
+
unique2("note_original_history", (row) => key2(uuid2(row.note_id), row.version_number));
|
|
9080
9868
|
rows("note_original_history").forEach((row, index) => {
|
|
9081
9869
|
ref(row, "note_id", notes, "note_original_history", index);
|
|
9082
9870
|
const current = originals.get(uuid2(row.note_id));
|
|
@@ -9088,7 +9876,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9088
9876
|
);
|
|
9089
9877
|
});
|
|
9090
9878
|
const revisionIds = ids2("note_revisions");
|
|
9091
|
-
unique2("note_revisions", (row) =>
|
|
9879
|
+
unique2("note_revisions", (row) => key2(uuid2(row.note_id), row.revision_number));
|
|
9092
9880
|
const revisions = new Map(rows("note_revisions").map((row) => [uuid2(row.id), row]));
|
|
9093
9881
|
rows("note_revisions").forEach((row, index) => {
|
|
9094
9882
|
ref(row, "note_id", notes, "note_revisions", index);
|
|
@@ -9143,7 +9931,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9143
9931
|
ref(row, "named_location_id", namedLocations, "provenance_locations", index, true);
|
|
9144
9932
|
});
|
|
9145
9933
|
const devices = ids2("provenance_devices");
|
|
9146
|
-
unique2("provenance_devices", (row) =>
|
|
9934
|
+
unique2("provenance_devices", (row) => key2(row.device_make, row.device_model, uuid2(row.owner_id)));
|
|
9147
9935
|
ids2("provenance_records");
|
|
9148
9936
|
unique2("provenance_records", (row) => uuid2(row.note_id));
|
|
9149
9937
|
rows("provenance_records").forEach((row, index) => {
|
|
@@ -9175,13 +9963,13 @@ function fullV1ReferenceErrors(records) {
|
|
|
9175
9963
|
const config = configRows.get(uuid2(row.embedding_config_id));
|
|
9176
9964
|
if (config) dimensions.set(uuid2(row.id), Number(row.truncate_dim ?? config.dimension));
|
|
9177
9965
|
});
|
|
9178
|
-
unique2("embedding_set_members", (row) =>
|
|
9966
|
+
unique2("embedding_set_members", (row) => key2(uuid2(row.embedding_set_id), uuid2(row.note_id)));
|
|
9179
9967
|
rows("embedding_set_members").forEach((row, index) => {
|
|
9180
9968
|
ref(row, "embedding_set_id", sets, "embedding_set_members", index);
|
|
9181
9969
|
ref(row, "note_id", notes, "embedding_set_members", index);
|
|
9182
9970
|
});
|
|
9183
9971
|
ids2("embeddings");
|
|
9184
|
-
unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ?
|
|
9972
|
+
unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ? key2(uuid2(row.note_id), uuid2(row.embedding_set_id), row.chunk_index) : null);
|
|
9185
9973
|
rows("embeddings").forEach((row, index) => {
|
|
9186
9974
|
ref(row, "note_id", notes, "embeddings", index, true);
|
|
9187
9975
|
ref(row, "embedding_set_id", sets, "embeddings", index, true);
|
|
@@ -9199,34 +9987,34 @@ function fullV1ReferenceErrors(records) {
|
|
|
9199
9987
|
unique2("skos_schemes", (row) => row.uri);
|
|
9200
9988
|
const concepts = ids2("skos_concepts");
|
|
9201
9989
|
unique2("skos_concepts", (row) => row.uri);
|
|
9202
|
-
unique2("skos_concepts", (row) => present(row.notation) ?
|
|
9990
|
+
unique2("skos_concepts", (row) => present(row.notation) ? key2(uuid2(row.primary_scheme_id), row.notation) : null);
|
|
9203
9991
|
rows("skos_concepts").forEach((row, index) => {
|
|
9204
9992
|
ref(row, "primary_scheme_id", schemes, "skos_concepts", index);
|
|
9205
9993
|
ref(row, "replaced_by_id", concepts, "skos_concepts", index, true);
|
|
9206
9994
|
check(uuid2(row.replaced_by_id) !== uuid2(row.id), "skos_concepts", index, "concept replaces itself");
|
|
9207
9995
|
});
|
|
9208
9996
|
ids2("skos_labels");
|
|
9209
|
-
unique2("skos_labels", (row) =>
|
|
9210
|
-
unique2("skos_labels", (row) => row.label_type === "pref_label" ?
|
|
9997
|
+
unique2("skos_labels", (row) => key2(uuid2(row.concept_id), row.label_type, row.language, row.value));
|
|
9998
|
+
unique2("skos_labels", (row) => row.label_type === "pref_label" ? key2(uuid2(row.concept_id), row.language) : null);
|
|
9211
9999
|
rows("skos_labels").forEach((row, index) => ref(row, "concept_id", concepts, "skos_labels", index));
|
|
9212
10000
|
ids2("skos_notes");
|
|
9213
10001
|
rows("skos_notes").forEach((row, index) => ref(row, "concept_id", concepts, "skos_notes", index));
|
|
9214
10002
|
ids2("skos_relations");
|
|
9215
|
-
unique2("skos_relations", (row) =>
|
|
10003
|
+
unique2("skos_relations", (row) => key2(uuid2(row.subject_id), uuid2(row.object_id), row.relation_type));
|
|
9216
10004
|
rows("skos_relations").forEach((row, index) => {
|
|
9217
10005
|
ref(row, "subject_id", concepts, "skos_relations", index);
|
|
9218
10006
|
ref(row, "object_id", concepts, "skos_relations", index);
|
|
9219
10007
|
check(uuid2(row.subject_id) !== uuid2(row.object_id), "skos_relations", index, "self relation is invalid");
|
|
9220
10008
|
});
|
|
9221
10009
|
ids2("skos_mapping_relations");
|
|
9222
|
-
unique2("skos_mapping_relations", (row) =>
|
|
10010
|
+
unique2("skos_mapping_relations", (row) => key2(uuid2(row.concept_id), row.target_uri, row.relation_type));
|
|
9223
10011
|
rows("skos_mapping_relations").forEach((row, index) => ref(row, "concept_id", concepts, "skos_mapping_relations", index));
|
|
9224
|
-
unique2("skos_scheme_memberships", (row) =>
|
|
10012
|
+
unique2("skos_scheme_memberships", (row) => key2(uuid2(row.concept_id), uuid2(row.scheme_id)));
|
|
9225
10013
|
rows("skos_scheme_memberships").forEach((row, index) => {
|
|
9226
10014
|
ref(row, "concept_id", concepts, "skos_scheme_memberships", index);
|
|
9227
10015
|
ref(row, "scheme_id", schemes, "skos_scheme_memberships", index);
|
|
9228
10016
|
});
|
|
9229
|
-
unique2("note_skos_tags", (row) =>
|
|
10017
|
+
unique2("note_skos_tags", (row) => key2(uuid2(row.note_id), uuid2(row.concept_id)));
|
|
9230
10018
|
rows("note_skos_tags").forEach((row, index) => {
|
|
9231
10019
|
ref(row, "note_id", notes, "note_skos_tags", index);
|
|
9232
10020
|
ref(row, "concept_id", concepts, "note_skos_tags", index);
|
|
@@ -9234,7 +10022,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9234
10022
|
const skosCollections = ids2("skos_collections");
|
|
9235
10023
|
unique2("skos_collections", (row) => row.uri);
|
|
9236
10024
|
rows("skos_collections").forEach((row, index) => ref(row, "scheme_id", schemes, "skos_collections", index, true));
|
|
9237
|
-
unique2("skos_collection_members", (row) =>
|
|
10025
|
+
unique2("skos_collection_members", (row) => key2(uuid2(row.collection_id), uuid2(row.concept_id)));
|
|
9238
10026
|
rows("skos_collection_members").forEach((row, index) => {
|
|
9239
10027
|
ref(row, "collection_id", skosCollections, "skos_collection_members", index);
|
|
9240
10028
|
ref(row, "concept_id", concepts, "skos_collection_members", index);
|
|
@@ -9250,7 +10038,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9250
10038
|
);
|
|
9251
10039
|
}
|
|
9252
10040
|
});
|
|
9253
|
-
unique2("graph_edges", (row) =>
|
|
10041
|
+
unique2("graph_edges", (row) => key2(row.graph_source_id, uuid2(row.from_note_id), uuid2(row.to_note_id), row.kind));
|
|
9254
10042
|
rows("graph_edges").forEach((row, index) => {
|
|
9255
10043
|
ref(row, "graph_source_id", sources, "graph_edges", index, false, false);
|
|
9256
10044
|
ref(row, "from_note_id", notes, "graph_edges", index);
|
|
@@ -9262,7 +10050,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
9262
10050
|
rows("communities").forEach((row, index) => {
|
|
9263
10051
|
ref(row, "graph_source_id", sources, "communities", index, false, false);
|
|
9264
10052
|
for (const community of row.communities) {
|
|
9265
|
-
const id =
|
|
10053
|
+
const id = key2(row.id, community.id);
|
|
9266
10054
|
check(!communities.has(id), "communities", index, "duplicate community identity within set");
|
|
9267
10055
|
communities.add(id);
|
|
9268
10056
|
const representatives = /* @__PURE__ */ new Set();
|
|
@@ -9277,10 +10065,10 @@ function fullV1ReferenceErrors(records) {
|
|
|
9277
10065
|
}
|
|
9278
10066
|
}
|
|
9279
10067
|
});
|
|
9280
|
-
unique2("community_assignments", (row) =>
|
|
10068
|
+
unique2("community_assignments", (row) => key2(row.community_set_id, uuid2(row.note_id)));
|
|
9281
10069
|
rows("community_assignments").forEach((row, index) => {
|
|
9282
10070
|
check(
|
|
9283
|
-
communities.has(
|
|
10071
|
+
communities.has(key2(row.community_set_id, row.community_id)),
|
|
9284
10072
|
"community_assignments",
|
|
9285
10073
|
index,
|
|
9286
10074
|
"community does not belong to the declared set"
|
|
@@ -19283,7 +20071,7 @@ function collectSidecarBlobs(files) {
|
|
|
19283
20071
|
}
|
|
19284
20072
|
|
|
19285
20073
|
// src/shard/schema-validator.ts
|
|
19286
|
-
var
|
|
20074
|
+
var decoder2 = new TextDecoder();
|
|
19287
20075
|
var LEGACY_COMPONENT_SCHEMA_DEFS = {
|
|
19288
20076
|
notes: "note",
|
|
19289
20077
|
collections: "collection",
|
|
@@ -19539,13 +20327,13 @@ function getKnowledgeShardSchema() {
|
|
|
19539
20327
|
function getKnowledgeShardContractReceipt() {
|
|
19540
20328
|
return knowledge_shard_schema_receipt_default;
|
|
19541
20329
|
}
|
|
19542
|
-
function addCanonicalFormats(
|
|
19543
|
-
|
|
19544
|
-
|
|
20330
|
+
function addCanonicalFormats(ajv3) {
|
|
20331
|
+
ajv3.addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
20332
|
+
ajv3.addFormat("date-time", {
|
|
19545
20333
|
type: "string",
|
|
19546
20334
|
validate: (value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && !Number.isNaN(Date.parse(value))
|
|
19547
20335
|
});
|
|
19548
|
-
|
|
20336
|
+
ajv3.addFormat("uri", {
|
|
19549
20337
|
type: "string",
|
|
19550
20338
|
validate: (value) => {
|
|
19551
20339
|
try {
|
|
@@ -19558,7 +20346,7 @@ function addCanonicalFormats(ajv2) {
|
|
|
19558
20346
|
}
|
|
19559
20347
|
function getLegacyAjv() {
|
|
19560
20348
|
if (!legacyAjvInstance) {
|
|
19561
|
-
legacyAjvInstance = new
|
|
20349
|
+
legacyAjvInstance = new Ajv20206({
|
|
19562
20350
|
allErrors: true,
|
|
19563
20351
|
strict: true,
|
|
19564
20352
|
validateFormats: false
|
|
@@ -19569,7 +20357,7 @@ function getLegacyAjv() {
|
|
|
19569
20357
|
}
|
|
19570
20358
|
function getCoreAjv() {
|
|
19571
20359
|
if (!coreAjvInstance) {
|
|
19572
|
-
coreAjvInstance = new
|
|
20360
|
+
coreAjvInstance = new Ajv20206({
|
|
19573
20361
|
allErrors: true,
|
|
19574
20362
|
strict: true,
|
|
19575
20363
|
validateFormats: true
|
|
@@ -19589,7 +20377,7 @@ function getCoreAjv() {
|
|
|
19589
20377
|
}
|
|
19590
20378
|
function getRecordAjv() {
|
|
19591
20379
|
if (!recordAjvInstance) {
|
|
19592
|
-
recordAjvInstance = new
|
|
20380
|
+
recordAjvInstance = new Ajv20206({
|
|
19593
20381
|
allErrors: true,
|
|
19594
20382
|
strict: true,
|
|
19595
20383
|
validateFormats: true
|
|
@@ -19609,7 +20397,7 @@ function getRecordAjv() {
|
|
|
19609
20397
|
}
|
|
19610
20398
|
function getFullAjv() {
|
|
19611
20399
|
if (!fullAjvInstance) {
|
|
19612
|
-
fullAjvInstance = new
|
|
20400
|
+
fullAjvInstance = new Ajv20206({
|
|
19613
20401
|
allErrors: true,
|
|
19614
20402
|
strict: true,
|
|
19615
20403
|
validateFormats: true
|
|
@@ -19644,30 +20432,30 @@ function fullSchemaVersion(value) {
|
|
|
19644
20432
|
return value === "1.1.0" || value === "1.2.0" || value === "2.0.0" ? value : void 0;
|
|
19645
20433
|
}
|
|
19646
20434
|
function coreValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19647
|
-
const
|
|
19648
|
-
const cached = coreValidators.get(
|
|
20435
|
+
const key3 = `${version}:${name}`;
|
|
20436
|
+
const cached = coreValidators.get(key3);
|
|
19649
20437
|
if (cached) return cached;
|
|
19650
20438
|
const schema = CORE_V1_SCHEMAS[version][name];
|
|
19651
20439
|
const validator = getCoreAjv().getSchema(schema.$id) ?? getCoreAjv().compile(schema);
|
|
19652
|
-
coreValidators.set(
|
|
20440
|
+
coreValidators.set(key3, validator);
|
|
19653
20441
|
return validator;
|
|
19654
20442
|
}
|
|
19655
20443
|
function recordValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19656
|
-
const
|
|
19657
|
-
const cached = recordValidators.get(
|
|
20444
|
+
const key3 = `${version}:${name}`;
|
|
20445
|
+
const cached = recordValidators.get(key3);
|
|
19658
20446
|
if (cached) return cached;
|
|
19659
20447
|
const schema = RECORD_V1_SCHEMAS[version][name];
|
|
19660
20448
|
const validator = getRecordAjv().getSchema(schema.$id) ?? getRecordAjv().compile(schema);
|
|
19661
|
-
recordValidators.set(
|
|
20449
|
+
recordValidators.set(key3, validator);
|
|
19662
20450
|
return validator;
|
|
19663
20451
|
}
|
|
19664
20452
|
function fullValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19665
|
-
const
|
|
19666
|
-
const cached = fullValidators.get(
|
|
20453
|
+
const key3 = `${version}:${name}`;
|
|
20454
|
+
const cached = fullValidators.get(key3);
|
|
19667
20455
|
if (cached) return cached;
|
|
19668
20456
|
const schema = FULL_V1_SCHEMAS[version][name];
|
|
19669
20457
|
const validator = getFullAjv().getSchema(schema.$id) ?? getFullAjv().compile(schema);
|
|
19670
|
-
fullValidators.set(
|
|
20458
|
+
fullValidators.set(key3, validator);
|
|
19671
20459
|
return validator;
|
|
19672
20460
|
}
|
|
19673
20461
|
function formatErrors(errors) {
|
|
@@ -19682,7 +20470,7 @@ function profileOf(value) {
|
|
|
19682
20470
|
return typeof profile === "string" ? profile : void 0;
|
|
19683
20471
|
}
|
|
19684
20472
|
function validateShardManifest(value) {
|
|
19685
|
-
let
|
|
20473
|
+
let validate4;
|
|
19686
20474
|
const profile = profileOf(value);
|
|
19687
20475
|
if (profile === "core-v1") {
|
|
19688
20476
|
const version = value && typeof value === "object" && !Array.isArray(value) ? coreSchemaVersion(String(value.version ?? "")) : void 0;
|
|
@@ -19692,7 +20480,7 @@ function validateShardManifest(value) {
|
|
|
19692
20480
|
errors: ["(root) uses an unsupported canonical core-v1 schema version"]
|
|
19693
20481
|
};
|
|
19694
20482
|
}
|
|
19695
|
-
|
|
20483
|
+
validate4 = coreValidatorFor("manifest", version);
|
|
19696
20484
|
} else if (profile === "record-v1") {
|
|
19697
20485
|
const version = value && typeof value === "object" && !Array.isArray(value) ? recordSchemaVersion(String(value.version ?? "")) : void 0;
|
|
19698
20486
|
if (!version) {
|
|
@@ -19701,7 +20489,7 @@ function validateShardManifest(value) {
|
|
|
19701
20489
|
errors: ["(root) uses an unsupported canonical record-v1 schema version"]
|
|
19702
20490
|
};
|
|
19703
20491
|
}
|
|
19704
|
-
|
|
20492
|
+
validate4 = recordValidatorFor("manifest", version);
|
|
19705
20493
|
} else if (profile === "full-v1") {
|
|
19706
20494
|
const version = value && typeof value === "object" && !Array.isArray(value) ? fullSchemaVersion(String(value.version ?? "")) : void 0;
|
|
19707
20495
|
if (!version) {
|
|
@@ -19710,17 +20498,17 @@ function validateShardManifest(value) {
|
|
|
19710
20498
|
errors: ["(root) uses an unsupported canonical full-v1 schema version"]
|
|
19711
20499
|
};
|
|
19712
20500
|
}
|
|
19713
|
-
|
|
20501
|
+
validate4 = fullValidatorFor("manifest", version);
|
|
19714
20502
|
} else {
|
|
19715
|
-
|
|
20503
|
+
validate4 = legacyValidatorFor("manifest");
|
|
19716
20504
|
}
|
|
19717
|
-
const valid =
|
|
19718
|
-
return { valid, errors: formatErrors(
|
|
20505
|
+
const valid = validate4(value);
|
|
20506
|
+
return { valid, errors: formatErrors(validate4.errors) };
|
|
19719
20507
|
}
|
|
19720
20508
|
function parseJsonArray(bytes, path) {
|
|
19721
20509
|
if (!bytes) return { records: [], errors: [] };
|
|
19722
20510
|
try {
|
|
19723
|
-
const value = JSON.parse(
|
|
20511
|
+
const value = JSON.parse(decoder2.decode(bytes));
|
|
19724
20512
|
if (!Array.isArray(value)) return { records: [], errors: [`${path} must be a JSON array`] };
|
|
19725
20513
|
return { records: value, errors: [] };
|
|
19726
20514
|
} catch {
|
|
@@ -19729,7 +20517,7 @@ function parseJsonArray(bytes, path) {
|
|
|
19729
20517
|
}
|
|
19730
20518
|
function parseJsonl(bytes, path) {
|
|
19731
20519
|
if (!bytes) return { records: [], errors: [] };
|
|
19732
|
-
const text =
|
|
20520
|
+
const text = decoder2.decode(bytes).trim();
|
|
19733
20521
|
if (!text) return { records: [], errors: [] };
|
|
19734
20522
|
const records = [];
|
|
19735
20523
|
const errors = [];
|
|
@@ -19973,7 +20761,7 @@ function validateFullV1Structure(files, manifest) {
|
|
|
19973
20761
|
const signatureBytes = files.get("signature.json");
|
|
19974
20762
|
if (signatureBytes) {
|
|
19975
20763
|
try {
|
|
19976
|
-
const signature = JSON.parse(
|
|
20764
|
+
const signature = JSON.parse(decoder2.decode(signatureBytes));
|
|
19977
20765
|
const signatureValidator = fullValidatorFor("signature", schemaVersion);
|
|
19978
20766
|
if (!signatureValidator(signature)) {
|
|
19979
20767
|
errors.push(
|
|
@@ -20069,7 +20857,7 @@ function validateShardArchive(input) {
|
|
|
20069
20857
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
20070
20858
|
let manifest;
|
|
20071
20859
|
try {
|
|
20072
|
-
manifest = JSON.parse(
|
|
20860
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
20073
20861
|
} catch {
|
|
20074
20862
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
20075
20863
|
}
|
|
@@ -20088,7 +20876,7 @@ async function validateCoreV1ShardArchive(input) {
|
|
|
20088
20876
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
20089
20877
|
let manifest;
|
|
20090
20878
|
try {
|
|
20091
|
-
manifest = JSON.parse(
|
|
20879
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
20092
20880
|
} catch {
|
|
20093
20881
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
20094
20882
|
}
|
|
@@ -20111,7 +20899,7 @@ async function validateRecordV1ShardArchive(input) {
|
|
|
20111
20899
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
20112
20900
|
let manifest;
|
|
20113
20901
|
try {
|
|
20114
|
-
manifest = JSON.parse(
|
|
20902
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
20115
20903
|
} catch {
|
|
20116
20904
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
20117
20905
|
}
|
|
@@ -20134,7 +20922,7 @@ async function validateFullV1ShardArchive(input) {
|
|
|
20134
20922
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
20135
20923
|
let manifest;
|
|
20136
20924
|
try {
|
|
20137
|
-
manifest = JSON.parse(
|
|
20925
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
20138
20926
|
} catch {
|
|
20139
20927
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
20140
20928
|
}
|
|
@@ -20163,9 +20951,9 @@ async function validateFullV1ShardArchive(input) {
|
|
|
20163
20951
|
return { valid: errors.length === 0, errors };
|
|
20164
20952
|
}
|
|
20165
20953
|
function validateShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
20166
|
-
let
|
|
20954
|
+
let validate4;
|
|
20167
20955
|
if (profile === "core-v1" && component in CORE_V1_COMPONENT_FILES) {
|
|
20168
|
-
|
|
20956
|
+
validate4 = coreValidatorFor(component, version);
|
|
20169
20957
|
} else if (profile === "record-v1" && component in RECORD_V1_COMPONENT_FILES) {
|
|
20170
20958
|
const canonicalVersion = recordSchemaVersion(version);
|
|
20171
20959
|
if (!canonicalVersion) {
|
|
@@ -20174,7 +20962,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
20174
20962
|
errors: [`(root) uses an unsupported canonical record-v1 schema version ${version}`]
|
|
20175
20963
|
};
|
|
20176
20964
|
}
|
|
20177
|
-
|
|
20965
|
+
validate4 = recordValidatorFor(component, canonicalVersion);
|
|
20178
20966
|
} else if (profile === "full-v1" && component in FULL_V1_COMPONENT_FILES) {
|
|
20179
20967
|
const canonicalVersion = fullSchemaVersion(version);
|
|
20180
20968
|
if (!canonicalVersion) {
|
|
@@ -20183,7 +20971,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
20183
20971
|
errors: [`(root) uses an unsupported canonical full-v1 schema version ${version}`]
|
|
20184
20972
|
};
|
|
20185
20973
|
}
|
|
20186
|
-
|
|
20974
|
+
validate4 = fullValidatorFor(component, canonicalVersion);
|
|
20187
20975
|
} else {
|
|
20188
20976
|
const legacyDef = LEGACY_COMPONENT_SCHEMA_DEFS[component];
|
|
20189
20977
|
if (!legacyDef) {
|
|
@@ -20192,10 +20980,10 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
20192
20980
|
errors: [`(root) component '${component}' requires an explicit full-v1 profile`]
|
|
20193
20981
|
};
|
|
20194
20982
|
}
|
|
20195
|
-
|
|
20983
|
+
validate4 = legacyValidatorFor(legacyDef);
|
|
20196
20984
|
}
|
|
20197
|
-
const valid =
|
|
20198
|
-
return { valid, errors: formatErrors(
|
|
20985
|
+
const valid = validate4(value);
|
|
20986
|
+
return { valid, errors: formatErrors(validate4.errors) };
|
|
20199
20987
|
}
|
|
20200
20988
|
function assertShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
20201
20989
|
const result = validateShardComponentRecord(component, value, profile, version);
|
|
@@ -20512,6 +21300,12 @@ var ManageNoteInputSchema = z.object({
|
|
|
20512
21300
|
});
|
|
20513
21301
|
var SearchInputSchema = z.object({
|
|
20514
21302
|
query: z.string(),
|
|
21303
|
+
metadataPredicates: z.unknown().transform((value) => {
|
|
21304
|
+
validateMetadataPredicates(value);
|
|
21305
|
+
return value;
|
|
21306
|
+
}).optional(),
|
|
21307
|
+
tenant_id: z.string().min(1).optional(),
|
|
21308
|
+
archive_id: z.string().min(1).nullable().optional(),
|
|
20515
21309
|
mode: z.enum(["text", "semantic", "hybrid", "auto"]).default("text"),
|
|
20516
21310
|
query_embedding: z.array(z.number()).optional(),
|
|
20517
21311
|
embeddingSetId: z.string().optional(),
|
|
@@ -20576,6 +21370,366 @@ async function manageNote(db, rawInput, events) {
|
|
|
20576
21370
|
|
|
20577
21371
|
// src/remote-contract.ts
|
|
20578
21372
|
init_geometry_buffer();
|
|
21373
|
+
|
|
21374
|
+
// src/remote-search-schema.ts
|
|
21375
|
+
init_geometry_buffer();
|
|
21376
|
+
|
|
21377
|
+
// schemas/metadata-search/candidate/1.0.0/search-rest.schema.json
|
|
21378
|
+
var search_rest_schema_default = {
|
|
21379
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
21380
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/search-rest.schema.json",
|
|
21381
|
+
title: "Candidate canonical GET search request and response",
|
|
21382
|
+
description: "Producer authority candidate. Schema validation is supplemented by same-note/canonical evidence binding, exact returned totals, strict-filter aggregate count and metadata range semantics. No auth grant or complete capability promotion.",
|
|
21383
|
+
$defs: {
|
|
21384
|
+
StrictSearchFilterInput: {
|
|
21385
|
+
type: "object",
|
|
21386
|
+
description: "Decoded strict_filter JSON. Unknown keys retain legacy ignored behavior. Sum of the five list lengths must not exceed 1000; name resolution still requires current authorized storage.",
|
|
21387
|
+
additionalProperties: true,
|
|
21388
|
+
properties: {
|
|
21389
|
+
required_tags: {
|
|
21390
|
+
type: "array",
|
|
21391
|
+
maxItems: 1e3,
|
|
21392
|
+
items: {
|
|
21393
|
+
type: "string"
|
|
21394
|
+
},
|
|
21395
|
+
default: []
|
|
21396
|
+
},
|
|
21397
|
+
any_tags: {
|
|
21398
|
+
type: "array",
|
|
21399
|
+
maxItems: 1e3,
|
|
21400
|
+
items: {
|
|
21401
|
+
type: "string"
|
|
21402
|
+
},
|
|
21403
|
+
default: []
|
|
21404
|
+
},
|
|
21405
|
+
excluded_tags: {
|
|
21406
|
+
type: "array",
|
|
21407
|
+
maxItems: 1e3,
|
|
21408
|
+
items: {
|
|
21409
|
+
type: "string"
|
|
21410
|
+
},
|
|
21411
|
+
default: []
|
|
21412
|
+
},
|
|
21413
|
+
required_schemes: {
|
|
21414
|
+
type: "array",
|
|
21415
|
+
maxItems: 1e3,
|
|
21416
|
+
items: {
|
|
21417
|
+
type: "string"
|
|
21418
|
+
},
|
|
21419
|
+
default: []
|
|
21420
|
+
},
|
|
21421
|
+
excluded_schemes: {
|
|
21422
|
+
type: "array",
|
|
21423
|
+
maxItems: 1e3,
|
|
21424
|
+
items: {
|
|
21425
|
+
type: "string"
|
|
21426
|
+
},
|
|
21427
|
+
default: []
|
|
21428
|
+
},
|
|
21429
|
+
min_tag_count: {
|
|
21430
|
+
type: ["integer", "null"],
|
|
21431
|
+
minimum: -2147483648,
|
|
21432
|
+
maximum: 2147483647
|
|
21433
|
+
},
|
|
21434
|
+
include_untagged: {
|
|
21435
|
+
type: "boolean",
|
|
21436
|
+
default: true
|
|
21437
|
+
}
|
|
21438
|
+
}
|
|
21439
|
+
},
|
|
21440
|
+
SearchRestRequest: {
|
|
21441
|
+
type: "object",
|
|
21442
|
+
description: "Decoded GET query parameters. JSON-content parameters are decoded to JSON values before this schema is applied. This is not a POST request body. Unknown query keys retain legacy ignored behavior and cannot grant tenant/archive authorization.",
|
|
21443
|
+
required: [
|
|
21444
|
+
"q"
|
|
21445
|
+
],
|
|
21446
|
+
additionalProperties: true,
|
|
21447
|
+
properties: {
|
|
21448
|
+
q: {
|
|
21449
|
+
type: "string",
|
|
21450
|
+
description: "Search expression. Empty text remains accepted."
|
|
21451
|
+
},
|
|
21452
|
+
limit: {
|
|
21453
|
+
type: "integer",
|
|
21454
|
+
minimum: 0,
|
|
21455
|
+
maximum: 1e3,
|
|
21456
|
+
default: 20
|
|
21457
|
+
},
|
|
21458
|
+
filters: {
|
|
21459
|
+
type: "string",
|
|
21460
|
+
description: "Legacy filter expression; combined with comma-separated tags."
|
|
21461
|
+
},
|
|
21462
|
+
mode: {
|
|
21463
|
+
type: "string",
|
|
21464
|
+
default: "hybrid",
|
|
21465
|
+
description: "fts selects lexical search, semantic selects vector search. hybrid, absent and other legacy values select hybrid; failures have explicit FTS degradation."
|
|
21466
|
+
},
|
|
21467
|
+
set: {
|
|
21468
|
+
type: "string",
|
|
21469
|
+
description: "Embedding-set slug resolved within the authorized memory and tenant."
|
|
21470
|
+
},
|
|
21471
|
+
created_after: {
|
|
21472
|
+
type: "string",
|
|
21473
|
+
format: "date-time"
|
|
21474
|
+
},
|
|
21475
|
+
created_before: {
|
|
21476
|
+
type: "string",
|
|
21477
|
+
format: "date-time"
|
|
21478
|
+
},
|
|
21479
|
+
updated_after: {
|
|
21480
|
+
type: "string",
|
|
21481
|
+
format: "date-time"
|
|
21482
|
+
},
|
|
21483
|
+
updated_before: {
|
|
21484
|
+
type: "string",
|
|
21485
|
+
format: "date-time"
|
|
21486
|
+
},
|
|
21487
|
+
since: {
|
|
21488
|
+
type: "string",
|
|
21489
|
+
description: "Relative created-after time; explicit created_after wins. Unrecognized relative text retains legacy ignored behavior."
|
|
21490
|
+
},
|
|
21491
|
+
tags: {
|
|
21492
|
+
type: "string",
|
|
21493
|
+
description: "Comma-separated tags; trimmed nonempty entries are AND requirements."
|
|
21494
|
+
},
|
|
21495
|
+
strict_filter: {
|
|
21496
|
+
$ref: "#/$defs/StrictSearchFilterInput",
|
|
21497
|
+
"x-fortemi-query-content": "application/json"
|
|
21498
|
+
},
|
|
21499
|
+
metadata_predicates: {
|
|
21500
|
+
$ref: "predicates.schema.json",
|
|
21501
|
+
"x-fortemi-query-content": "application/json",
|
|
21502
|
+
"x-fortemi-max-encoded-utf8-bytes": 1048576
|
|
21503
|
+
},
|
|
21504
|
+
diversity: {
|
|
21505
|
+
type: "number",
|
|
21506
|
+
minimum: -34028234663852886e22,
|
|
21507
|
+
maximum: 34028234663852886e22,
|
|
21508
|
+
description: "Finite f32 input, clamped to [0,1] before MMR; zero is pure relevance."
|
|
21509
|
+
}
|
|
21510
|
+
}
|
|
21511
|
+
},
|
|
21512
|
+
SearchHitFields: {
|
|
21513
|
+
type: "object",
|
|
21514
|
+
required: [
|
|
21515
|
+
"note_id",
|
|
21516
|
+
"score",
|
|
21517
|
+
"snippet"
|
|
21518
|
+
],
|
|
21519
|
+
properties: {
|
|
21520
|
+
note_id: {
|
|
21521
|
+
type: "string",
|
|
21522
|
+
format: "uuid"
|
|
21523
|
+
},
|
|
21524
|
+
score: {
|
|
21525
|
+
type: "number",
|
|
21526
|
+
description: "Finite retrieval/fusion score, not a probability."
|
|
21527
|
+
},
|
|
21528
|
+
snippet: {
|
|
21529
|
+
type: [
|
|
21530
|
+
"string",
|
|
21531
|
+
"null"
|
|
21532
|
+
],
|
|
21533
|
+
description: "Display only; not citation text or coordinates."
|
|
21534
|
+
},
|
|
21535
|
+
title: {
|
|
21536
|
+
type: "string"
|
|
21537
|
+
},
|
|
21538
|
+
tags: {
|
|
21539
|
+
type: "array",
|
|
21540
|
+
items: {
|
|
21541
|
+
type: "string"
|
|
21542
|
+
}
|
|
21543
|
+
},
|
|
21544
|
+
embedding_status: {
|
|
21545
|
+
enum: [
|
|
21546
|
+
"ready",
|
|
21547
|
+
"pending",
|
|
21548
|
+
"failed",
|
|
21549
|
+
"none"
|
|
21550
|
+
]
|
|
21551
|
+
},
|
|
21552
|
+
evidence: {
|
|
21553
|
+
$ref: "evidence-set.schema.json"
|
|
21554
|
+
}
|
|
21555
|
+
}
|
|
21556
|
+
},
|
|
21557
|
+
SearchHit: {
|
|
21558
|
+
type: "object",
|
|
21559
|
+
allOf: [
|
|
21560
|
+
{
|
|
21561
|
+
$ref: "#/$defs/SearchHitFields"
|
|
21562
|
+
}
|
|
21563
|
+
],
|
|
21564
|
+
unevaluatedProperties: false
|
|
21565
|
+
},
|
|
21566
|
+
ChainSearchInfo: {
|
|
21567
|
+
type: "object",
|
|
21568
|
+
additionalProperties: false,
|
|
21569
|
+
required: [
|
|
21570
|
+
"chain_id",
|
|
21571
|
+
"original_title",
|
|
21572
|
+
"chunks_matched",
|
|
21573
|
+
"best_chunk_sequence",
|
|
21574
|
+
"total_chunks"
|
|
21575
|
+
],
|
|
21576
|
+
description: "Legacy display aggregation. Index/count fields are currently heuristic, not native citation coordinates; use evidence for exact unit identity.",
|
|
21577
|
+
properties: {
|
|
21578
|
+
chain_id: {
|
|
21579
|
+
type: "string",
|
|
21580
|
+
format: "uuid"
|
|
21581
|
+
},
|
|
21582
|
+
original_title: {
|
|
21583
|
+
type: "string"
|
|
21584
|
+
},
|
|
21585
|
+
chunks_matched: {
|
|
21586
|
+
type: "integer",
|
|
21587
|
+
minimum: 0
|
|
21588
|
+
},
|
|
21589
|
+
best_chunk_sequence: {
|
|
21590
|
+
type: "integer",
|
|
21591
|
+
minimum: 0,
|
|
21592
|
+
maximum: 4294967295
|
|
21593
|
+
},
|
|
21594
|
+
total_chunks: {
|
|
21595
|
+
type: "integer",
|
|
21596
|
+
minimum: 0,
|
|
21597
|
+
maximum: 4294967295
|
|
21598
|
+
}
|
|
21599
|
+
}
|
|
21600
|
+
},
|
|
21601
|
+
EnhancedSearchHit: {
|
|
21602
|
+
type: "object",
|
|
21603
|
+
allOf: [
|
|
21604
|
+
{
|
|
21605
|
+
$ref: "#/$defs/SearchHitFields"
|
|
21606
|
+
},
|
|
21607
|
+
{
|
|
21608
|
+
type: "object",
|
|
21609
|
+
properties: {
|
|
21610
|
+
chain_info: {
|
|
21611
|
+
$ref: "#/$defs/ChainSearchInfo"
|
|
21612
|
+
}
|
|
21613
|
+
}
|
|
21614
|
+
}
|
|
21615
|
+
],
|
|
21616
|
+
unevaluatedProperties: false
|
|
21617
|
+
},
|
|
21618
|
+
SearchDegradation: {
|
|
21619
|
+
type: "object",
|
|
21620
|
+
additionalProperties: false,
|
|
21621
|
+
required: [
|
|
21622
|
+
"code",
|
|
21623
|
+
"effective_mode"
|
|
21624
|
+
],
|
|
21625
|
+
properties: {
|
|
21626
|
+
code: {
|
|
21627
|
+
type: "string",
|
|
21628
|
+
pattern: "^[a-z][a-z0-9_]{0,63}$"
|
|
21629
|
+
},
|
|
21630
|
+
effective_mode: {
|
|
21631
|
+
const: "fts"
|
|
21632
|
+
}
|
|
21633
|
+
}
|
|
21634
|
+
},
|
|
21635
|
+
SearchRestResponse: {
|
|
21636
|
+
type: "object",
|
|
21637
|
+
additionalProperties: false,
|
|
21638
|
+
required: [
|
|
21639
|
+
"results",
|
|
21640
|
+
"query",
|
|
21641
|
+
"total",
|
|
21642
|
+
"degraded"
|
|
21643
|
+
],
|
|
21644
|
+
properties: {
|
|
21645
|
+
results: {
|
|
21646
|
+
type: "array",
|
|
21647
|
+
maxItems: 1e3,
|
|
21648
|
+
items: {
|
|
21649
|
+
$ref: "#/$defs/EnhancedSearchHit"
|
|
21650
|
+
}
|
|
21651
|
+
},
|
|
21652
|
+
query: {
|
|
21653
|
+
type: "string"
|
|
21654
|
+
},
|
|
21655
|
+
total: {
|
|
21656
|
+
type: "integer",
|
|
21657
|
+
minimum: 0,
|
|
21658
|
+
maximum: 1e3,
|
|
21659
|
+
description: "Returned hit count, exactly results.length; not total matches in storage."
|
|
21660
|
+
},
|
|
21661
|
+
degraded: {
|
|
21662
|
+
type: "boolean"
|
|
21663
|
+
},
|
|
21664
|
+
degradation: {
|
|
21665
|
+
$ref: "#/$defs/SearchDegradation"
|
|
21666
|
+
}
|
|
21667
|
+
},
|
|
21668
|
+
if: {
|
|
21669
|
+
properties: {
|
|
21670
|
+
degraded: {
|
|
21671
|
+
const: true
|
|
21672
|
+
}
|
|
21673
|
+
}
|
|
21674
|
+
},
|
|
21675
|
+
then: {
|
|
21676
|
+
properties: {
|
|
21677
|
+
degradation: {}
|
|
21678
|
+
},
|
|
21679
|
+
required: [
|
|
21680
|
+
"degradation"
|
|
21681
|
+
]
|
|
21682
|
+
},
|
|
21683
|
+
else: {
|
|
21684
|
+
not: {
|
|
21685
|
+
properties: {
|
|
21686
|
+
degradation: {}
|
|
21687
|
+
},
|
|
21688
|
+
required: [
|
|
21689
|
+
"degradation"
|
|
21690
|
+
]
|
|
21691
|
+
}
|
|
21692
|
+
}
|
|
21693
|
+
}
|
|
21694
|
+
}
|
|
21695
|
+
};
|
|
21696
|
+
|
|
21697
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-resolution.schema.json
|
|
21698
|
+
var evidence_resolution_schema_default = {
|
|
21699
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
21700
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-resolution.schema.json",
|
|
21701
|
+
title: "Candidate current-storage evidence resolution",
|
|
21702
|
+
$defs: {
|
|
21703
|
+
SearchEvidenceResolveRequest: {
|
|
21704
|
+
type: "object",
|
|
21705
|
+
additionalProperties: false,
|
|
21706
|
+
required: ["locator"],
|
|
21707
|
+
properties: {
|
|
21708
|
+
locator: { $ref: "evidence-locator.schema.json" },
|
|
21709
|
+
metadata_predicates: { $ref: "predicates.schema.json" },
|
|
21710
|
+
include_archived: { type: "boolean", default: false }
|
|
21711
|
+
}
|
|
21712
|
+
},
|
|
21713
|
+
SearchEvidenceResolveResponse: {
|
|
21714
|
+
type: "object",
|
|
21715
|
+
additionalProperties: false,
|
|
21716
|
+
required: ["text"],
|
|
21717
|
+
properties: {
|
|
21718
|
+
text: { type: "string", maxLength: 16777216 }
|
|
21719
|
+
}
|
|
21720
|
+
}
|
|
21721
|
+
}
|
|
21722
|
+
};
|
|
21723
|
+
|
|
21724
|
+
// src/remote-search-schema.ts
|
|
21725
|
+
var timestamp = z.string().datetime({ offset: true });
|
|
21726
|
+
var ajv2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).addFormat("date-time", { type: "string", validate: (value) => timestamp.safeParse(value).success }).addKeyword({ keyword: "x-fortemi-query-content", schemaType: "string", valid: true }).addKeyword({ keyword: "x-fortemi-max-encoded-utf8-bytes", schemaType: "number", valid: true }).addSchema([search_rest_schema_default, evidence_locator_schema_default, evidence_set_schema_default, evidence_resolution_schema_default]).addSchema(predicates_schema_default, new URL("predicates.schema.json", search_rest_schema_default.$id).href);
|
|
21727
|
+
var isSearchRestRequest = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestRequest" });
|
|
21728
|
+
var isSearchRestResponse = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestResponse" });
|
|
21729
|
+
var isEvidenceResolveRequest = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveRequest" });
|
|
21730
|
+
var isEvidenceResolveResponse = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveResponse" });
|
|
21731
|
+
|
|
21732
|
+
// src/remote-contract.ts
|
|
20579
21733
|
var uuid3 = z.string().uuid().transform((value) => value.toLowerCase());
|
|
20580
21734
|
var metadata = z.object({
|
|
20581
21735
|
id: uuid3,
|
|
@@ -20618,7 +21772,7 @@ function parseRemoteNoteDetail(value) {
|
|
|
20618
21772
|
return { ...projectNote({ ...result.note, tags: result.tags }), content: result.revised.content };
|
|
20619
21773
|
});
|
|
20620
21774
|
}
|
|
20621
|
-
var
|
|
21775
|
+
var timestamp2 = z.string().datetime({ offset: true });
|
|
20622
21776
|
function remoteNoteId(value) {
|
|
20623
21777
|
const parsed = uuid3.safeParse(value);
|
|
20624
21778
|
if (!parsed.success) throw new RemoteBackendError("invalid-request");
|
|
@@ -20631,7 +21785,7 @@ var link = z.object({
|
|
|
20631
21785
|
to_url: z.string().nullable(),
|
|
20632
21786
|
kind: z.string(),
|
|
20633
21787
|
score: z.number().finite(),
|
|
20634
|
-
created_at_utc:
|
|
21788
|
+
created_at_utc: timestamp2,
|
|
20635
21789
|
snippet: z.string().nullable(),
|
|
20636
21790
|
metadata: z.unknown().refine((value) => value !== void 0)
|
|
20637
21791
|
});
|
|
@@ -20670,7 +21824,7 @@ var conceptAssignment = z.tuple([
|
|
|
20670
21824
|
source: z.string(),
|
|
20671
21825
|
relevance_score: z.number().finite(),
|
|
20672
21826
|
is_primary: z.boolean(),
|
|
20673
|
-
created_at:
|
|
21827
|
+
created_at: timestamp2,
|
|
20674
21828
|
confidence: z.number().finite().optional(),
|
|
20675
21829
|
created_by: z.string().optional()
|
|
20676
21830
|
}),
|
|
@@ -20678,8 +21832,8 @@ var conceptAssignment = z.tuple([
|
|
|
20678
21832
|
id: uuid3,
|
|
20679
21833
|
primary_scheme_id: uuid3,
|
|
20680
21834
|
pref_label: z.string(),
|
|
20681
|
-
created_at:
|
|
20682
|
-
updated_at:
|
|
21835
|
+
created_at: timestamp2,
|
|
21836
|
+
updated_at: timestamp2
|
|
20683
21837
|
})
|
|
20684
21838
|
]);
|
|
20685
21839
|
function parseRemoteConcepts(value, noteId) {
|
|
@@ -20714,8 +21868,8 @@ var provenanceActivity = z.object({
|
|
|
20714
21868
|
revision_id: uuid3.nullable(),
|
|
20715
21869
|
activity_type: z.string(),
|
|
20716
21870
|
model_name: z.string().nullable(),
|
|
20717
|
-
started_at:
|
|
20718
|
-
ended_at:
|
|
21871
|
+
started_at: timestamp2,
|
|
21872
|
+
ended_at: timestamp2.nullable(),
|
|
20719
21873
|
metadata: z.unknown().refine((value) => value !== void 0)
|
|
20720
21874
|
});
|
|
20721
21875
|
var provenanceEdge = z.object({
|
|
@@ -20724,7 +21878,7 @@ var provenanceEdge = z.object({
|
|
|
20724
21878
|
source_note_id: uuid3.nullable(),
|
|
20725
21879
|
source_url: z.string().nullable(),
|
|
20726
21880
|
relation: z.string(),
|
|
20727
|
-
created_at_utc:
|
|
21881
|
+
created_at_utc: timestamp2
|
|
20728
21882
|
});
|
|
20729
21883
|
var provenanceChain = z.object({
|
|
20730
21884
|
note_id: uuid3,
|
|
@@ -20762,12 +21916,14 @@ function remoteSearchParameters(query, options) {
|
|
|
20762
21916
|
if (typeof query !== "string" || !parsed.success) throw new RemoteBackendError("invalid-request");
|
|
20763
21917
|
const value = parsed.data;
|
|
20764
21918
|
if ((value.offset ?? 0) !== 0 || (value.source?.length ?? 0) > 0) throw new RemoteBackendError("unsupported-operation");
|
|
20765
|
-
|
|
21919
|
+
const parameters = {
|
|
20766
21920
|
q: query,
|
|
20767
21921
|
mode: value.mode,
|
|
20768
21922
|
limit: value.limit,
|
|
20769
21923
|
...value.tags?.length ? { tags: value.tags.join(",") } : {}
|
|
20770
21924
|
};
|
|
21925
|
+
if (!isSearchRestRequest(parameters)) throw new RemoteBackendError("invalid-request");
|
|
21926
|
+
return parameters;
|
|
20771
21927
|
}
|
|
20772
21928
|
var searchHit = z.object({
|
|
20773
21929
|
note_id: uuid3,
|
|
@@ -20776,6 +21932,7 @@ var searchHit = z.object({
|
|
|
20776
21932
|
title: z.string().optional(),
|
|
20777
21933
|
tags: z.array(z.string()).optional(),
|
|
20778
21934
|
embedding_status: z.enum(["ready", "pending", "failed", "none"]).optional(),
|
|
21935
|
+
evidence: z.unknown().optional(),
|
|
20779
21936
|
chain_info: z.object({
|
|
20780
21937
|
chain_id: uuid3,
|
|
20781
21938
|
original_title: z.string(),
|
|
@@ -20783,10 +21940,13 @@ var searchHit = z.object({
|
|
|
20783
21940
|
best_chunk_sequence: z.number().int().nonnegative(),
|
|
20784
21941
|
total_chunks: z.number().int().nonnegative()
|
|
20785
21942
|
}).optional()
|
|
20786
|
-
})
|
|
21943
|
+
}).transform(({ evidence, ...hit }) => ({
|
|
21944
|
+
...hit,
|
|
21945
|
+
...evidence === void 0 ? {} : { evidence: parseSearchEvidenceSet(evidence, hit.note_id) }
|
|
21946
|
+
}));
|
|
20787
21947
|
var searchDegradation = z.object({
|
|
20788
21948
|
code: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
20789
|
-
effective_mode:
|
|
21949
|
+
effective_mode: z.literal("fts")
|
|
20790
21950
|
});
|
|
20791
21951
|
var searchResponse = z.object({
|
|
20792
21952
|
query: z.string(),
|
|
@@ -20797,8 +21957,10 @@ var searchResponse = z.object({
|
|
|
20797
21957
|
});
|
|
20798
21958
|
function parseRemoteSearch(value, query, limit) {
|
|
20799
21959
|
return remoteProjection(() => {
|
|
21960
|
+
if (!isSearchRestResponse(value)) throw new Error("Invalid search schema");
|
|
20800
21961
|
const result = searchResponse.parse(value);
|
|
20801
21962
|
if (result.query !== query || result.total !== result.results.length || result.results.length > limit || result.degraded !== (result.degradation !== void 0)) throw new Error("Invalid search envelope");
|
|
21963
|
+
if (result.results.some((hit) => hit.chain_info && hit.chain_info.chain_id !== hit.note_id)) throw new Error("Invalid chain identity");
|
|
20802
21964
|
return result;
|
|
20803
21965
|
});
|
|
20804
21966
|
}
|
|
@@ -20834,6 +21996,135 @@ function parseRemoteRestored(value, id) {
|
|
|
20834
21996
|
});
|
|
20835
21997
|
}
|
|
20836
21998
|
|
|
21999
|
+
// src/backend-search-options.ts
|
|
22000
|
+
init_geometry_buffer();
|
|
22001
|
+
function validateBackendSearchOptions(options, support) {
|
|
22002
|
+
if (options?.metadataPredicates !== void 0) {
|
|
22003
|
+
validateMetadataPredicates(options.metadataPredicates);
|
|
22004
|
+
if (!support.metadata) throw new Error("BACKEND_METADATA_PREDICATES_UNSUPPORTED");
|
|
22005
|
+
}
|
|
22006
|
+
if (options?.tenant_id !== void 0 || options?.archive_id !== void 0) {
|
|
22007
|
+
if (!support.scope) throw new Error("BACKEND_SEARCH_SCOPE_UNSUPPORTED");
|
|
22008
|
+
if (options.tenant_id !== void 0 && (typeof options.tenant_id !== "string" || !options.tenant_id.length) || options.archive_id !== void 0 && options.archive_id !== null && (typeof options.archive_id !== "string" || !options.archive_id.length)) {
|
|
22009
|
+
throw new Error("BACKEND_SEARCH_SCOPE_INVALID");
|
|
22010
|
+
}
|
|
22011
|
+
}
|
|
22012
|
+
if (options?.mode !== void 0 && support.modes && !support.modes.includes(options.mode)) {
|
|
22013
|
+
throw new Error("BACKEND_SEARCH_MODE_UNSUPPORTED");
|
|
22014
|
+
}
|
|
22015
|
+
}
|
|
22016
|
+
|
|
22017
|
+
// src/remote-evidence-resolution.ts
|
|
22018
|
+
init_geometry_buffer();
|
|
22019
|
+
var encoder3 = new TextEncoder();
|
|
22020
|
+
var decoder3 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
22021
|
+
var invalidRequest = () => new RemoteBackendError("invalid-request");
|
|
22022
|
+
var invalidResponse = () => new RemoteBackendError("invalid-response");
|
|
22023
|
+
function prepare(value, options = {}) {
|
|
22024
|
+
try {
|
|
22025
|
+
if (!options || typeof options !== "object" || Array.isArray(options) || ![Object.prototype, null].includes(Object.getPrototypeOf(options)) || Reflect.ownKeys(options).some((key3) => !["metadataPredicates", "includeArchived", "signal"].includes(String(key3)))) throw invalidRequest();
|
|
22026
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
22027
|
+
if (locator.span.end > MAX_EVIDENCE_BYTES) throw invalidRequest();
|
|
22028
|
+
const metadata2 = Object.hasOwn(options, "metadataPredicates") ? options.metadataPredicates : void 0;
|
|
22029
|
+
const archived = Object.hasOwn(options, "includeArchived") ? options.includeArchived : void 0;
|
|
22030
|
+
const signal = Object.hasOwn(options, "signal") ? options.signal : void 0;
|
|
22031
|
+
if (signal !== void 0 && !(signal instanceof AbortSignal)) throw invalidRequest();
|
|
22032
|
+
if (metadata2 !== void 0) validateMetadataPredicates(metadata2);
|
|
22033
|
+
const request = {
|
|
22034
|
+
locator,
|
|
22035
|
+
...metadata2 === void 0 ? {} : { metadata_predicates: metadata2 },
|
|
22036
|
+
...archived === void 0 ? {} : { include_archived: archived }
|
|
22037
|
+
};
|
|
22038
|
+
if (!isEvidenceResolveRequest(request)) throw invalidRequest();
|
|
22039
|
+
const body = JSON.stringify(request);
|
|
22040
|
+
if (encoder3.encode(body).length > 65536) throw invalidRequest();
|
|
22041
|
+
const wire = JSON.parse(body);
|
|
22042
|
+
if (!isEvidenceResolveRequest(wire)) throw invalidRequest();
|
|
22043
|
+
const encoded = wire;
|
|
22044
|
+
parseSearchEvidenceLocator(encoded.locator);
|
|
22045
|
+
if (encoded.metadata_predicates !== void 0) validateMetadataPredicates(encoded.metadata_predicates);
|
|
22046
|
+
return { body, signal, length: locator.span.end - locator.span.start };
|
|
22047
|
+
} catch {
|
|
22048
|
+
throw invalidRequest();
|
|
22049
|
+
}
|
|
22050
|
+
}
|
|
22051
|
+
async function resolveRemoteEvidence(value, options, send) {
|
|
22052
|
+
const prepared = prepare(value, options);
|
|
22053
|
+
if (prepared.signal?.aborted) throw new RemoteBackendError("aborted");
|
|
22054
|
+
const controller = new AbortController();
|
|
22055
|
+
const abort = () => controller.abort();
|
|
22056
|
+
prepared.signal?.addEventListener("abort", abort, { once: true });
|
|
22057
|
+
const timer = setTimeout(abort, 3e4);
|
|
22058
|
+
let reader;
|
|
22059
|
+
let completed = false;
|
|
22060
|
+
let rejectAbort = () => {
|
|
22061
|
+
};
|
|
22062
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
22063
|
+
rejectAbort = () => reject(new RemoteBackendError("aborted"));
|
|
22064
|
+
});
|
|
22065
|
+
controller.signal.addEventListener("abort", rejectAbort, { once: true });
|
|
22066
|
+
async function perform() {
|
|
22067
|
+
const response = await send(prepared.body, controller.signal);
|
|
22068
|
+
if (controller.signal.aborted) {
|
|
22069
|
+
void response.body?.cancel().catch(() => {
|
|
22070
|
+
});
|
|
22071
|
+
throw new RemoteBackendError("aborted");
|
|
22072
|
+
}
|
|
22073
|
+
reader = response.body?.getReader();
|
|
22074
|
+
if (!response.ok) throw new RemoteBackendError("http", response.status);
|
|
22075
|
+
if (response.status !== 200 || !reader || response.headers.get("content-type")?.split(";")[0].trim().toLowerCase() !== "application/json" || !response.headers.get("cache-control")?.split(",").some((part) => part.trim().toLowerCase() === "no-store")) throw invalidResponse();
|
|
22076
|
+
const maximum = prepared.length * 6 + 64;
|
|
22077
|
+
const advertised = response.headers.get("content-length");
|
|
22078
|
+
if (advertised !== null && (!/^\d+$/.test(advertised) || Number(advertised) > maximum)) throw invalidResponse();
|
|
22079
|
+
let bytes = new Uint8Array(Math.min(maximum, 4096));
|
|
22080
|
+
let length = 0;
|
|
22081
|
+
while (true) {
|
|
22082
|
+
const { done, value: chunk } = await reader.read();
|
|
22083
|
+
if (done) {
|
|
22084
|
+
completed = true;
|
|
22085
|
+
break;
|
|
22086
|
+
}
|
|
22087
|
+
const nextLength = length + chunk.byteLength;
|
|
22088
|
+
if (nextLength > maximum) throw invalidResponse();
|
|
22089
|
+
if (nextLength > bytes.length) {
|
|
22090
|
+
const grown = new Uint8Array(Math.min(maximum, Math.max(nextLength, bytes.length * 2)));
|
|
22091
|
+
grown.set(bytes.subarray(0, length));
|
|
22092
|
+
bytes = grown;
|
|
22093
|
+
}
|
|
22094
|
+
bytes.set(chunk, length);
|
|
22095
|
+
length = nextLength;
|
|
22096
|
+
}
|
|
22097
|
+
let data;
|
|
22098
|
+
try {
|
|
22099
|
+
data = JSON.parse(decoder3.decode(bytes.subarray(0, length)));
|
|
22100
|
+
} catch {
|
|
22101
|
+
throw invalidResponse();
|
|
22102
|
+
}
|
|
22103
|
+
if (!isEvidenceResolveResponse(data)) throw invalidResponse();
|
|
22104
|
+
const text = data.text;
|
|
22105
|
+
if (text.length > prepared.length) throw invalidResponse();
|
|
22106
|
+
const textBytes2 = encoder3.encode(text);
|
|
22107
|
+
if (textBytes2.length !== prepared.length || decoder3.decode(textBytes2) !== text) throw invalidResponse();
|
|
22108
|
+
return text;
|
|
22109
|
+
}
|
|
22110
|
+
try {
|
|
22111
|
+
return await Promise.race([perform(), aborted]);
|
|
22112
|
+
} catch (error) {
|
|
22113
|
+
if (error instanceof RemoteBackendError) throw error;
|
|
22114
|
+
throw new RemoteBackendError(controller.signal.aborted || error instanceof Error && error.name === "AbortError" ? "aborted" : "transport");
|
|
22115
|
+
} finally {
|
|
22116
|
+
clearTimeout(timer);
|
|
22117
|
+
prepared.signal?.removeEventListener("abort", abort);
|
|
22118
|
+
controller.signal.removeEventListener("abort", rejectAbort);
|
|
22119
|
+
controller.abort();
|
|
22120
|
+
if (reader) {
|
|
22121
|
+
if (!completed) void reader.cancel().catch(() => {
|
|
22122
|
+
});
|
|
22123
|
+
reader.releaseLock();
|
|
22124
|
+
}
|
|
22125
|
+
}
|
|
22126
|
+
}
|
|
22127
|
+
|
|
20837
22128
|
// src/data-backend.ts
|
|
20838
22129
|
var SEMANTIC_RANK = {
|
|
20839
22130
|
none: 0,
|
|
@@ -20848,6 +22139,8 @@ var STARTUP_RANK = {
|
|
|
20848
22139
|
};
|
|
20849
22140
|
function missingFor(request, caps) {
|
|
20850
22141
|
const missing = [];
|
|
22142
|
+
if (request.typedMetadataPredicates && !caps.typedMetadataPredicates) missing.push("typedMetadataPredicates");
|
|
22143
|
+
if (request.evidenceLocators && !caps.evidenceLocators) missing.push("evidenceLocators");
|
|
20851
22144
|
if (request.read && !caps.read) missing.push("read");
|
|
20852
22145
|
if (request.write && !caps.write) missing.push("write");
|
|
20853
22146
|
if (request.merge && !caps.merge) missing.push("merge");
|
|
@@ -20971,9 +22264,45 @@ function shardProvenanceToBackend(edge) {
|
|
|
20971
22264
|
}
|
|
20972
22265
|
function createPGliteBackend(db, options = {}) {
|
|
20973
22266
|
const semanticAvailable = options.semanticAvailable ?? false;
|
|
22267
|
+
const embedQuery = options.embedQuery;
|
|
22268
|
+
const canEmbed = semanticAvailable && typeof embedQuery === "function";
|
|
20974
22269
|
const notes = new NotesRepository(db);
|
|
20975
22270
|
const search = new SearchRepository(db, semanticAvailable);
|
|
20976
22271
|
const links = new LinksRepository(db);
|
|
22272
|
+
async function searchNotes(query, o) {
|
|
22273
|
+
validateBackendSearchOptions(o, {
|
|
22274
|
+
metadata: true,
|
|
22275
|
+
scope: true,
|
|
22276
|
+
modes: canEmbed ? ["fts", "semantic", "hybrid"] : ["fts"]
|
|
22277
|
+
});
|
|
22278
|
+
const mode = o?.mode ?? "fts";
|
|
22279
|
+
const vector = mode === "fts" ? void 0 : await embedQuery(query);
|
|
22280
|
+
if (mode !== "fts" && (!Array.isArray(vector) || !vector.length || !Array.from(vector).every((value) => typeof value === "number" && Number.isFinite(value)))) {
|
|
22281
|
+
throw new Error("BACKEND_QUERY_EMBEDDING_INVALID");
|
|
22282
|
+
}
|
|
22283
|
+
const r = await search.search(query, {
|
|
22284
|
+
limit: o?.limit,
|
|
22285
|
+
offset: o?.offset,
|
|
22286
|
+
tagsAll: o?.tags,
|
|
22287
|
+
sources: o?.source,
|
|
22288
|
+
mode: mode === "fts" ? "text" : mode,
|
|
22289
|
+
metadataPredicates: o?.metadataPredicates,
|
|
22290
|
+
tenant_id: o?.tenant_id,
|
|
22291
|
+
archive_id: o?.archive_id,
|
|
22292
|
+
include_facets: true
|
|
22293
|
+
}, vector);
|
|
22294
|
+
return {
|
|
22295
|
+
hits: r.results.map((res) => ({
|
|
22296
|
+
note: searchResultToBackend(res),
|
|
22297
|
+
rank: res.rank,
|
|
22298
|
+
snippet: res.snippet,
|
|
22299
|
+
locators: res.locators,
|
|
22300
|
+
evidence: res.evidence
|
|
22301
|
+
})),
|
|
22302
|
+
total: r.total,
|
|
22303
|
+
facets: r.facets ? { tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count])) } : void 0
|
|
22304
|
+
};
|
|
22305
|
+
}
|
|
20977
22306
|
async function linksOf(id) {
|
|
20978
22307
|
const result = await links.listForNote(id);
|
|
20979
22308
|
const urlLinks = await db.query(
|
|
@@ -21014,7 +22343,9 @@ function createPGliteBackend(db, options = {}) {
|
|
|
21014
22343
|
write: true,
|
|
21015
22344
|
merge: true,
|
|
21016
22345
|
multiUser: false,
|
|
21017
|
-
|
|
22346
|
+
typedMetadataPredicates: true,
|
|
22347
|
+
evidenceLocators: false,
|
|
22348
|
+
semantic: canEmbed ? "ann-full" : "none",
|
|
21018
22349
|
startupCost: "index-build"
|
|
21019
22350
|
},
|
|
21020
22351
|
async listNotes(o) {
|
|
@@ -21029,24 +22360,8 @@ function createPGliteBackend(db, options = {}) {
|
|
|
21029
22360
|
return null;
|
|
21030
22361
|
}
|
|
21031
22362
|
},
|
|
21032
|
-
|
|
21033
|
-
|
|
21034
|
-
limit: o?.limit,
|
|
21035
|
-
offset: o?.offset,
|
|
21036
|
-
tags: o?.tags,
|
|
21037
|
-
source: o?.source?.[0],
|
|
21038
|
-
include_facets: true
|
|
21039
|
-
});
|
|
21040
|
-
const hits = r.results.map((res) => ({
|
|
21041
|
-
note: searchResultToBackend(res),
|
|
21042
|
-
rank: res.rank,
|
|
21043
|
-
snippet: res.snippet
|
|
21044
|
-
}));
|
|
21045
|
-
const facets = r.facets ? {
|
|
21046
|
-
tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count]))
|
|
21047
|
-
} : void 0;
|
|
21048
|
-
return { hits, total: r.total, facets };
|
|
21049
|
-
},
|
|
22363
|
+
search: searchNotes,
|
|
22364
|
+
...canEmbed ? { semantic: async (query, k) => (await searchNotes(query, { mode: "semantic", limit: k })).hits } : {},
|
|
21050
22365
|
async getNoteFull(id) {
|
|
21051
22366
|
try {
|
|
21052
22367
|
const f = await notes.get(id);
|
|
@@ -21072,6 +22387,7 @@ var DEFAULT_REMOTE_PATHS = {
|
|
|
21072
22387
|
notes: "/api/v1/notes",
|
|
21073
22388
|
note: "/api/v1/notes/:id",
|
|
21074
22389
|
search: "/api/v1/search",
|
|
22390
|
+
resolveEvidence: "/api/v1/search/evidence/resolve",
|
|
21075
22391
|
links: "/api/v1/notes/:id/links",
|
|
21076
22392
|
concepts: "/api/v1/notes/:id/concepts",
|
|
21077
22393
|
provenance: "/api/v1/notes/:id/provenance",
|
|
@@ -21082,12 +22398,12 @@ function remotePath(template, id) {
|
|
|
21082
22398
|
}
|
|
21083
22399
|
function remoteUrl(baseUrl, path, params) {
|
|
21084
22400
|
const url = new URL(path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
21085
|
-
for (const [
|
|
22401
|
+
for (const [key3, value] of Object.entries(params ?? {})) {
|
|
21086
22402
|
if (value === void 0) continue;
|
|
21087
22403
|
if (Array.isArray(value)) {
|
|
21088
|
-
for (const item of value) url.searchParams.append(
|
|
22404
|
+
for (const item of value) url.searchParams.append(key3, String(item));
|
|
21089
22405
|
} else {
|
|
21090
|
-
url.searchParams.set(
|
|
22406
|
+
url.searchParams.set(key3, String(value));
|
|
21091
22407
|
}
|
|
21092
22408
|
}
|
|
21093
22409
|
return url.toString();
|
|
@@ -21143,6 +22459,7 @@ function createRemoteBackend(config) {
|
|
|
21143
22459
|
return note;
|
|
21144
22460
|
}
|
|
21145
22461
|
async function searchRemote(query, options, requireSemantic = false) {
|
|
22462
|
+
validateBackendSearchOptions(options, { metadata: false, scope: false });
|
|
21146
22463
|
const params = remoteSearchParameters(query, options);
|
|
21147
22464
|
const result = parseRemoteSearch(await getJson(paths.search, params), query, params.limit);
|
|
21148
22465
|
if (requireSemantic && result.degraded) throw new RemoteBackendError("degraded-search");
|
|
@@ -21167,6 +22484,7 @@ function createRemoteBackend(config) {
|
|
|
21167
22484
|
},
|
|
21168
22485
|
rank: hit.score,
|
|
21169
22486
|
...hit.snippet === null ? {} : { snippet: hit.snippet },
|
|
22487
|
+
...hit.evidence === void 0 ? {} : { evidence: hit.evidence },
|
|
21170
22488
|
remoteSearch: {
|
|
21171
22489
|
...hit.title === void 0 ? {} : { title: hit.title },
|
|
21172
22490
|
...hit.tags === void 0 ? {} : { tags: hit.tags },
|
|
@@ -21223,6 +22541,8 @@ function createRemoteBackend(config) {
|
|
|
21223
22541
|
merge: false,
|
|
21224
22542
|
multiUser: true,
|
|
21225
22543
|
semantic: "server",
|
|
22544
|
+
typedMetadataPredicates: false,
|
|
22545
|
+
evidenceLocators: false,
|
|
21226
22546
|
startupCost: "network"
|
|
21227
22547
|
},
|
|
21228
22548
|
async listNotes(o) {
|
|
@@ -21250,6 +22570,20 @@ function createRemoteBackend(config) {
|
|
|
21250
22570
|
}
|
|
21251
22571
|
},
|
|
21252
22572
|
search: searchRemote,
|
|
22573
|
+
async resolveEvidence(locator, options) {
|
|
22574
|
+
return resolveRemoteEvidence(locator, options, async (body, signal) => {
|
|
22575
|
+
const headers = await remoteHeaders(config, true);
|
|
22576
|
+
signal.throwIfAborted();
|
|
22577
|
+
return (config.fetchImpl ?? globalThis.fetch)(remoteUrl(config.baseUrl, paths.resolveEvidence ?? DEFAULT_REMOTE_PATHS.resolveEvidence), {
|
|
22578
|
+
method: "POST",
|
|
22579
|
+
headers,
|
|
22580
|
+
body,
|
|
22581
|
+
signal,
|
|
22582
|
+
cache: "no-store",
|
|
22583
|
+
redirect: "error"
|
|
22584
|
+
});
|
|
22585
|
+
});
|
|
22586
|
+
},
|
|
21253
22587
|
getNoteFull,
|
|
21254
22588
|
linksOf,
|
|
21255
22589
|
conceptsOf,
|
|
@@ -21319,6 +22653,8 @@ function createShardBackend(reader, options = {}) {
|
|
|
21319
22653
|
merge: false,
|
|
21320
22654
|
multiUser: false,
|
|
21321
22655
|
semantic,
|
|
22656
|
+
typedMetadataPredicates: false,
|
|
22657
|
+
evidenceLocators: false,
|
|
21322
22658
|
startupCost: "instant"
|
|
21323
22659
|
},
|
|
21324
22660
|
async listNotes(o) {
|
|
@@ -21330,6 +22666,7 @@ function createShardBackend(reader, options = {}) {
|
|
|
21330
22666
|
return n ? shardNoteToBackend(n) : null;
|
|
21331
22667
|
},
|
|
21332
22668
|
async search(query, o) {
|
|
22669
|
+
validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
|
|
21333
22670
|
const r = await reader.search(query, { ...o, rank: true, snippets: true });
|
|
21334
22671
|
const hits = r.rankedItems ? r.rankedItems.map((it) => ({
|
|
21335
22672
|
note: shardNoteToBackend(it.note),
|
|
@@ -21873,26 +23210,26 @@ function isRecord(value) {
|
|
|
21873
23210
|
function isSupportedState(value) {
|
|
21874
23211
|
return typeof value === "string" && FORTEMI_COMPATIBILITY_STATES.includes(value);
|
|
21875
23212
|
}
|
|
21876
|
-
function requireRecord(parent,
|
|
21877
|
-
const value = parent[
|
|
23213
|
+
function requireRecord(parent, key3, errors) {
|
|
23214
|
+
const value = parent[key3];
|
|
21878
23215
|
if (!isRecord(value)) {
|
|
21879
|
-
errors.push(`${
|
|
23216
|
+
errors.push(`${key3} must be an object`);
|
|
21880
23217
|
return null;
|
|
21881
23218
|
}
|
|
21882
23219
|
return value;
|
|
21883
23220
|
}
|
|
21884
|
-
function requireString(parent,
|
|
21885
|
-
const value = parent[
|
|
23221
|
+
function requireString(parent, key3, path, errors) {
|
|
23222
|
+
const value = parent[key3];
|
|
21886
23223
|
if (typeof value !== "string" || value.length === 0) {
|
|
21887
|
-
errors.push(`${path}.${
|
|
23224
|
+
errors.push(`${path}.${key3} must be a non-empty string`);
|
|
21888
23225
|
return null;
|
|
21889
23226
|
}
|
|
21890
23227
|
return value;
|
|
21891
23228
|
}
|
|
21892
|
-
function requireBoolean(parent,
|
|
21893
|
-
const value = parent[
|
|
23229
|
+
function requireBoolean(parent, key3, path, errors) {
|
|
23230
|
+
const value = parent[key3];
|
|
21894
23231
|
if (typeof value !== "boolean") {
|
|
21895
|
-
errors.push(`${path}.${
|
|
23232
|
+
errors.push(`${path}.${key3} must be a boolean`);
|
|
21896
23233
|
return null;
|
|
21897
23234
|
}
|
|
21898
23235
|
return value;
|
|
@@ -21942,24 +23279,24 @@ function validateFortemiCompatibilityResponse(raw) {
|
|
|
21942
23279
|
}
|
|
21943
23280
|
const capabilities = requireRecord(raw, "capabilities", errors);
|
|
21944
23281
|
if (capabilities) {
|
|
21945
|
-
for (const
|
|
21946
|
-
if (!isRecord(capabilities[
|
|
21947
|
-
errors.push(`capabilities.${
|
|
23282
|
+
for (const key3 of FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES) {
|
|
23283
|
+
if (!isRecord(capabilities[key3])) {
|
|
23284
|
+
errors.push(`capabilities.${key3} must be present as an object`);
|
|
21948
23285
|
}
|
|
21949
23286
|
}
|
|
21950
|
-
for (const [
|
|
23287
|
+
for (const [key3, value] of Object.entries(capabilities)) {
|
|
21951
23288
|
if (!isRecord(value)) {
|
|
21952
|
-
errors.push(`capabilities.${
|
|
23289
|
+
errors.push(`capabilities.${key3} must be an object`);
|
|
21953
23290
|
continue;
|
|
21954
23291
|
}
|
|
21955
23292
|
if (!isSupportedState(value.state)) {
|
|
21956
|
-
errors.push(`capabilities.${
|
|
23293
|
+
errors.push(`capabilities.${key3}.state must be one of ${FORTEMI_COMPATIBILITY_STATES.join(", ")}`);
|
|
21957
23294
|
}
|
|
21958
23295
|
if ("reason_code" in value && typeof value.reason_code !== "string") {
|
|
21959
|
-
errors.push(`capabilities.${
|
|
23296
|
+
errors.push(`capabilities.${key3}.reason_code must be a string when present`);
|
|
21960
23297
|
}
|
|
21961
23298
|
if (value.state !== "available" && !value.reason_code) {
|
|
21962
|
-
warnings.push(`capabilities.${
|
|
23299
|
+
warnings.push(`capabilities.${key3} is ${String(value.state)} without reason_code`);
|
|
21963
23300
|
}
|
|
21964
23301
|
}
|
|
21965
23302
|
}
|
|
@@ -21978,7 +23315,7 @@ function validateFortemiCompatibilityResponse(raw) {
|
|
|
21978
23315
|
};
|
|
21979
23316
|
}
|
|
21980
23317
|
function formatFortemiCompatibilitySummary(response) {
|
|
21981
|
-
const capabilitySummary = Object.entries(response.capabilities).map(([
|
|
23318
|
+
const capabilitySummary = Object.entries(response.capabilities).map(([key3, value]) => `${key3}=${value.state}`).sort().join(", ");
|
|
21982
23319
|
return [
|
|
21983
23320
|
`Fortemi compatibility ${response.contract_revision}`,
|
|
21984
23321
|
`api=${response.api.name}@${response.api.version}`,
|
|
@@ -24291,7 +25628,7 @@ var CollectionsRepository = class {
|
|
|
24291
25628
|
|
|
24292
25629
|
// src/repositories/templates-repository.ts
|
|
24293
25630
|
init_geometry_buffer();
|
|
24294
|
-
function
|
|
25631
|
+
function validate2(record) {
|
|
24295
25632
|
if (!validateShardComponentRecord("templates", record, "full-v1", "2.0.0").valid) throw new Error("Invalid native template");
|
|
24296
25633
|
}
|
|
24297
25634
|
var TemplatesRepository = class {
|
|
@@ -24309,7 +25646,7 @@ var TemplatesRepository = class {
|
|
|
24309
25646
|
async create(input) {
|
|
24310
25647
|
const id = generateId();
|
|
24311
25648
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
24312
|
-
|
|
25649
|
+
validate2({
|
|
24313
25650
|
id,
|
|
24314
25651
|
name: input.name,
|
|
24315
25652
|
content: input.content,
|
|
@@ -24329,13 +25666,13 @@ var TemplatesRepository = class {
|
|
|
24329
25666
|
}
|
|
24330
25667
|
async update(id, input) {
|
|
24331
25668
|
const current = await this.get(id);
|
|
24332
|
-
|
|
25669
|
+
validate2({ ...current, ...Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0)) });
|
|
24333
25670
|
const values = [];
|
|
24334
25671
|
const assignments = ["updated_at = now()"];
|
|
24335
|
-
for (const
|
|
24336
|
-
if (input[
|
|
24337
|
-
values.push(
|
|
24338
|
-
assignments.push(`${
|
|
25672
|
+
for (const key3 of ["name", "content", "description", "format", "default_tags", "collection_id"]) {
|
|
25673
|
+
if (input[key3] === void 0) continue;
|
|
25674
|
+
values.push(key3 === "default_tags" ? JSON.stringify(input[key3]) : input[key3]);
|
|
25675
|
+
assignments.push(`${key3} = $${values.length}${key3 === "default_tags" ? "::jsonb" : ""}`);
|
|
24339
25676
|
}
|
|
24340
25677
|
values.push(id);
|
|
24341
25678
|
await this.db.query(`UPDATE template SET ${assignments.join(", ")} WHERE id = $${values.length}`, values);
|
|
@@ -24496,8 +25833,8 @@ async function removeOmittedNativeSkos(tx, state, selectedNoteIds3) {
|
|
|
24496
25833
|
await tx.query(
|
|
24497
25834
|
`DELETE FROM ${table} existing WHERE existing.${owner} = ANY($1::text[])
|
|
24498
25835
|
AND NOT EXISTS (SELECT 1 FROM UNNEST(${keys.map((_, index) => `$${index + 2}::text[]`).join(", ")}) incoming(${keys.join(", ")})
|
|
24499
|
-
WHERE ${keys.map((
|
|
24500
|
-
[selected, ...keys.map((
|
|
25836
|
+
WHERE ${keys.map((key3) => `incoming.${key3} = existing.${key3}`).join(" AND ")})`,
|
|
25837
|
+
[selected, ...keys.map((key3) => incoming.map((row) => nativeUuid(row[key3])))]
|
|
24501
25838
|
);
|
|
24502
25839
|
}
|
|
24503
25840
|
}
|
|
@@ -25036,8 +26373,8 @@ async function captureKnowledge(db, rawInput, events) {
|
|
|
25036
26373
|
if (!input.template) throw new Error("template is required for from_template action");
|
|
25037
26374
|
let content = input.template;
|
|
25038
26375
|
if (input.variables) {
|
|
25039
|
-
for (const [
|
|
25040
|
-
content = content.replaceAll(`{{${
|
|
26376
|
+
for (const [key3, value] of Object.entries(input.variables)) {
|
|
26377
|
+
content = content.replaceAll(`{{${key3}}}`, value);
|
|
25041
26378
|
}
|
|
25042
26379
|
}
|
|
25043
26380
|
const note = await repo.create({
|
|
@@ -25063,6 +26400,9 @@ async function searchTool(db, rawInput) {
|
|
|
25063
26400
|
}
|
|
25064
26401
|
const repo = new SearchRepository(db, semanticAvailable);
|
|
25065
26402
|
return repo.search(input.query, {
|
|
26403
|
+
metadataPredicates: input.metadataPredicates,
|
|
26404
|
+
tenant_id: input.tenant_id,
|
|
26405
|
+
archive_id: input.archive_id,
|
|
25066
26406
|
limit: input.limit,
|
|
25067
26407
|
offset: input.offset,
|
|
25068
26408
|
mode: input.mode,
|
|
@@ -25087,10 +26427,10 @@ function zodToJsonSchema(schema) {
|
|
|
25087
26427
|
const shape = schema.shape;
|
|
25088
26428
|
const properties = {};
|
|
25089
26429
|
const required = [];
|
|
25090
|
-
for (const [
|
|
25091
|
-
properties[
|
|
26430
|
+
for (const [key3, value] of Object.entries(shape)) {
|
|
26431
|
+
properties[key3] = resolvePropertySchema(value);
|
|
25092
26432
|
if (!(value instanceof z.ZodOptional) && !(value instanceof z.ZodDefault)) {
|
|
25093
|
-
required.push(
|
|
26433
|
+
required.push(key3);
|
|
25094
26434
|
}
|
|
25095
26435
|
}
|
|
25096
26436
|
return {
|
|
@@ -27154,13 +28494,13 @@ var OpenAICompatibleProvider = class {
|
|
|
27154
28494
|
throw new Error("Streaming not supported: response body is null");
|
|
27155
28495
|
}
|
|
27156
28496
|
const reader = response.body.getReader();
|
|
27157
|
-
const
|
|
28497
|
+
const decoder10 = new TextDecoder();
|
|
27158
28498
|
let buffer = "";
|
|
27159
28499
|
try {
|
|
27160
28500
|
while (true) {
|
|
27161
28501
|
const { done, value } = await reader.read();
|
|
27162
28502
|
if (done) break;
|
|
27163
|
-
buffer +=
|
|
28503
|
+
buffer += decoder10.decode(value, { stream: true });
|
|
27164
28504
|
const lines = buffer.split("\n");
|
|
27165
28505
|
buffer = lines.pop() ?? "";
|
|
27166
28506
|
for (const line of lines) {
|
|
@@ -28221,8 +29561,8 @@ var AllowlistTrustStore = class {
|
|
|
28221
29561
|
}
|
|
28222
29562
|
/** Mark a key revoked without removing it (still resolvable, verdict `revoked`). */
|
|
28223
29563
|
revoke(keyId) {
|
|
28224
|
-
const
|
|
28225
|
-
if (
|
|
29564
|
+
const key3 = this.keys.get(keyId);
|
|
29565
|
+
if (key3) this.keys.set(keyId, { ...key3, revoked: true });
|
|
28226
29566
|
}
|
|
28227
29567
|
};
|
|
28228
29568
|
function base64urlToBytes(s) {
|
|
@@ -28310,7 +29650,7 @@ async function verifyShardSignature(input) {
|
|
|
28310
29650
|
};
|
|
28311
29651
|
let signatureValid = false;
|
|
28312
29652
|
try {
|
|
28313
|
-
const
|
|
29653
|
+
const key3 = await globalThis.crypto.subtle.importKey(
|
|
28314
29654
|
"raw",
|
|
28315
29655
|
toBufferSource(base64urlToBytes(trusted.public_key)),
|
|
28316
29656
|
{ name: "Ed25519" },
|
|
@@ -28320,7 +29660,7 @@ async function verifyShardSignature(input) {
|
|
|
28320
29660
|
const digest2 = await sha256Hex(canonicalPayloadBytes(payload));
|
|
28321
29661
|
signatureValid = await globalThis.crypto.subtle.verify(
|
|
28322
29662
|
"Ed25519",
|
|
28323
|
-
|
|
29663
|
+
key3,
|
|
28324
29664
|
toBufferSource(base64urlToBytes(envelope.signature)),
|
|
28325
29665
|
toBufferSource(new TextEncoder().encode(digest2))
|
|
28326
29666
|
);
|
|
@@ -36933,8 +38273,8 @@ function classifyPresenceValue(value) {
|
|
|
36933
38273
|
function classifyOwnProperty(document2, pointer) {
|
|
36934
38274
|
const resolved = parentAndKey(document2, pointer, false);
|
|
36935
38275
|
if (!resolved) return "absent";
|
|
36936
|
-
const { parent, key:
|
|
36937
|
-
return Object.hasOwn(parent,
|
|
38276
|
+
const { parent, key: key3 } = resolved;
|
|
38277
|
+
return Object.hasOwn(parent, key3) ? classifyPresenceValue(parent[key3]) : "absent";
|
|
36938
38278
|
}
|
|
36939
38279
|
function capturePresence(document2, pointers) {
|
|
36940
38280
|
return Object.fromEntries(pointers.flatMap(
|
|
@@ -36986,14 +38326,14 @@ function restoreStoredPresence(document2, presence) {
|
|
|
36986
38326
|
for (const [pointer, stored] of Object.entries(presence)) {
|
|
36987
38327
|
const resolved = parentAndKey(restored, pointer);
|
|
36988
38328
|
if (!resolved) throw new Error(`JSON Pointer '${pointer}' parent is not an object`);
|
|
36989
|
-
const { parent, key:
|
|
38329
|
+
const { parent, key: key3 } = resolved;
|
|
36990
38330
|
if (stored === "legacy-indeterminate") {
|
|
36991
38331
|
throw new Error(`Cannot emit schema 2.0 with legacy-indeterminate state at ${pointer}`);
|
|
36992
38332
|
}
|
|
36993
38333
|
if (stored === "absent") {
|
|
36994
|
-
delete parent[
|
|
38334
|
+
delete parent[key3];
|
|
36995
38335
|
} else if (stored === "null") {
|
|
36996
|
-
parent[
|
|
38336
|
+
parent[key3] = null;
|
|
36997
38337
|
} else if (classifyOwnProperty(restored, pointer) !== stored) {
|
|
36998
38338
|
throw new Error(`Stored ${stored} state at ${pointer} does not match the persisted value`);
|
|
36999
38339
|
}
|
|
@@ -37312,7 +38652,7 @@ var rowKey = (component, row) => nativeIdentityKey(nativeIdentities[component],
|
|
|
37312
38652
|
function canonical(value) {
|
|
37313
38653
|
if (Array.isArray(value)) return value.map(canonical);
|
|
37314
38654
|
if (value !== null && typeof value === "object") return Object.fromEntries(
|
|
37315
|
-
Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([
|
|
38655
|
+
Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key3, item]) => [key3, canonical(item)])
|
|
37316
38656
|
);
|
|
37317
38657
|
return value;
|
|
37318
38658
|
}
|
|
@@ -37374,7 +38714,7 @@ async function readNativeLineage(tx, state) {
|
|
|
37374
38714
|
|
|
37375
38715
|
// src/shard/live-full-v1.ts
|
|
37376
38716
|
var components2 = Object.keys(FULL_V1_COMPONENT_FILES);
|
|
37377
|
-
var
|
|
38717
|
+
var encoder4 = new TextEncoder();
|
|
37378
38718
|
var scoped = (values) => values ? [...values] : void 0;
|
|
37379
38719
|
var ids = (rows) => new Set(rows.map((row) => row.id));
|
|
37380
38720
|
var nullableIn = (set, value) => value === null || set.has(value);
|
|
@@ -37710,7 +39050,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37710
39050
|
for (const component of components2) {
|
|
37711
39051
|
const spec = FULL_V1_COMPONENT_FILES[component];
|
|
37712
39052
|
const rows = state[component];
|
|
37713
|
-
const bytes =
|
|
39053
|
+
const bytes = encoder4.encode(spec.encoding === "json-array" ? JSON.stringify(rows) : rows.map((row) => JSON.stringify(row)).join("\n"));
|
|
37714
39054
|
files.set(spec.file, bytes);
|
|
37715
39055
|
counts[component] = rows.length;
|
|
37716
39056
|
checksums[spec.file] = await sha256Hex(bytes);
|
|
@@ -37749,7 +39089,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37749
39089
|
capability = { ...capability, losses: manifestLosses };
|
|
37750
39090
|
return failure2("Generated live full-v1 manifest violates presence authority.");
|
|
37751
39091
|
}
|
|
37752
|
-
files.set("manifest.json",
|
|
39092
|
+
files.set("manifest.json", encoder4.encode(JSON.stringify(manifest, null, 2)));
|
|
37753
39093
|
for (const note of state.notes) for (const { attachment } of note.attachments) {
|
|
37754
39094
|
const path = sidecarEntryName(attachment.checksum);
|
|
37755
39095
|
if (files.has(path)) continue;
|
|
@@ -37772,7 +39112,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37772
39112
|
}
|
|
37773
39113
|
|
|
37774
39114
|
// src/shard/shard-export.ts
|
|
37775
|
-
var
|
|
39115
|
+
var encoder5 = new TextEncoder();
|
|
37776
39116
|
var CORE_V1_FILES = /* @__PURE__ */ new Set([
|
|
37777
39117
|
"notes.jsonl",
|
|
37778
39118
|
"collections.json",
|
|
@@ -38178,11 +39518,11 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38178
39518
|
const slice = shardNotes.slice(offset, offset + clusterSize);
|
|
38179
39519
|
const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
|
|
38180
39520
|
clusters.push({ href, offset });
|
|
38181
|
-
files.set(href,
|
|
39521
|
+
files.set(href, encoder5.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
|
|
38182
39522
|
}
|
|
38183
39523
|
layout = { clusters: { notes: clusters } };
|
|
38184
39524
|
} else {
|
|
38185
|
-
files.set("notes.jsonl",
|
|
39525
|
+
files.set("notes.jsonl", encoder5.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
|
|
38186
39526
|
}
|
|
38187
39527
|
components4.push("notes");
|
|
38188
39528
|
counts.notes = notes.length;
|
|
@@ -38210,7 +39550,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38210
39550
|
mode?.nativeSchema2Presence
|
|
38211
39551
|
);
|
|
38212
39552
|
}
|
|
38213
|
-
files.set("collections.json",
|
|
39553
|
+
files.set("collections.json", encoder5.encode(JSON.stringify(shardCollections)));
|
|
38214
39554
|
components4.push("collections");
|
|
38215
39555
|
counts.collections = shardCollections.length;
|
|
38216
39556
|
const allTagRows = await db.query(
|
|
@@ -38226,7 +39566,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38226
39566
|
const shardTags = tagsToShard(
|
|
38227
39567
|
relevantTags.map((r) => ({ name: r.tag, created_at: r.created_at }))
|
|
38228
39568
|
);
|
|
38229
|
-
files.set("tags.json",
|
|
39569
|
+
files.set("tags.json", encoder5.encode(JSON.stringify(shardTags)));
|
|
38230
39570
|
components4.push("tags");
|
|
38231
39571
|
counts.tags = shardTags.length;
|
|
38232
39572
|
const templateRows = await db.query(`SELECT * FROM template ORDER BY created_at, id`);
|
|
@@ -38242,7 +39582,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38242
39582
|
mode?.nativeSchema2Presence
|
|
38243
39583
|
);
|
|
38244
39584
|
}
|
|
38245
|
-
files.set("templates.json",
|
|
39585
|
+
files.set("templates.json", encoder5.encode(JSON.stringify(shardTemplates)));
|
|
38246
39586
|
components4.push("templates");
|
|
38247
39587
|
counts.templates = shardTemplates.length;
|
|
38248
39588
|
}
|
|
@@ -38267,7 +39607,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38267
39607
|
);
|
|
38268
39608
|
}
|
|
38269
39609
|
const linksJsonl = shardLinks.map((l) => JSON.stringify(l)).join("\n");
|
|
38270
|
-
files.set("links.jsonl",
|
|
39610
|
+
files.set("links.jsonl", encoder5.encode(linksJsonl));
|
|
38271
39611
|
components4.push("links");
|
|
38272
39612
|
counts.links = shardLinks.length;
|
|
38273
39613
|
const allNoteSkosRows = await db.query(`SELECT * FROM note_skos_tag ORDER BY created_at`);
|
|
@@ -38284,25 +39624,25 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38284
39624
|
(row) => exportedConceptIds.has(row.source_concept_id) && exportedConceptIds.has(row.target_concept_id)
|
|
38285
39625
|
) : allRelationRows.rows;
|
|
38286
39626
|
const shardSkosSchemes = filteredSchemeRows.map(skosSchemeToShard);
|
|
38287
|
-
files.set("skos_schemes.json",
|
|
39627
|
+
files.set("skos_schemes.json", encoder5.encode(JSON.stringify(shardSkosSchemes)));
|
|
38288
39628
|
components4.push("skos_schemes");
|
|
38289
39629
|
counts.skos_schemes = shardSkosSchemes.length;
|
|
38290
39630
|
const shardSkosConcepts = filteredConceptRows.map(skosConceptToShard);
|
|
38291
|
-
files.set("skos_concepts.json",
|
|
39631
|
+
files.set("skos_concepts.json", encoder5.encode(JSON.stringify(shardSkosConcepts)));
|
|
38292
39632
|
components4.push("skos_concepts");
|
|
38293
39633
|
counts.skos_concepts = shardSkosConcepts.length;
|
|
38294
39634
|
const skosRelationsJsonl = filteredRelationRows.map((row) => JSON.stringify(skosRelationToShard(row))).join("\n");
|
|
38295
|
-
files.set("skos_relations.jsonl",
|
|
39635
|
+
files.set("skos_relations.jsonl", encoder5.encode(skosRelationsJsonl));
|
|
38296
39636
|
components4.push("skos_relations");
|
|
38297
39637
|
counts.skos_relations = filteredRelationRows.length;
|
|
38298
39638
|
const noteSkosJsonl = filteredNoteSkosRows.map((row) => JSON.stringify(noteSkosTagToShard(row))).join("\n");
|
|
38299
|
-
files.set("note_skos_tags.jsonl",
|
|
39639
|
+
files.set("note_skos_tags.jsonl", encoder5.encode(noteSkosJsonl));
|
|
38300
39640
|
components4.push("note_skos_tags");
|
|
38301
39641
|
counts.note_skos_tags = filteredNoteSkosRows.length;
|
|
38302
39642
|
const provenanceRows = await db.query(`SELECT * FROM provenance_edge ORDER BY started_at`);
|
|
38303
39643
|
const filteredProvenanceRows = isFiltered ? provenanceRows.rows.filter((row) => row.entity_type !== "note" || exportedNoteIds.has(row.entity_id)) : provenanceRows.rows;
|
|
38304
39644
|
const provenanceJsonl = filteredProvenanceRows.map((row) => JSON.stringify(provenanceEdgeToShard(row))).join("\n");
|
|
38305
|
-
files.set("provenance_edges.jsonl",
|
|
39645
|
+
files.set("provenance_edges.jsonl", encoder5.encode(provenanceJsonl));
|
|
38306
39646
|
components4.push("provenance_edges");
|
|
38307
39647
|
counts.provenance_edges = filteredProvenanceRows.length;
|
|
38308
39648
|
if (options?.includeEmbeddings) {
|
|
@@ -38342,7 +39682,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38342
39682
|
freshness_json: { status: "unknown" }
|
|
38343
39683
|
} : row
|
|
38344
39684
|
));
|
|
38345
|
-
files.set("embedding_sets.json",
|
|
39685
|
+
files.set("embedding_sets.json", encoder5.encode(JSON.stringify(shardEmbSets)));
|
|
38346
39686
|
components4.push("embedding_sets");
|
|
38347
39687
|
counts.embedding_sets = shardEmbSets.length;
|
|
38348
39688
|
const embeddingConfigRows = await db.query(
|
|
@@ -38352,7 +39692,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38352
39692
|
);
|
|
38353
39693
|
if (embeddingConfigRows.rows.length > 0) {
|
|
38354
39694
|
const shardEmbeddingConfigs = embeddingConfigRows.rows.map((row) => embeddingConfigToShard(row));
|
|
38355
|
-
files.set("embedding_configs.json",
|
|
39695
|
+
files.set("embedding_configs.json", encoder5.encode(JSON.stringify(shardEmbeddingConfigs)));
|
|
38356
39696
|
components4.push("embedding_configs");
|
|
38357
39697
|
counts.embedding_configs = shardEmbeddingConfigs.length;
|
|
38358
39698
|
}
|
|
@@ -38365,7 +39705,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38365
39705
|
(member) => exportedSetIds.has(member.embedding_set_id) && exportedNoteIds.has(member.note_id) && (includeMaterializedSelectors || !virtualSetIds.has(member.embedding_set_id))
|
|
38366
39706
|
);
|
|
38367
39707
|
const membersJsonl = scopedEmbMemberRows.map((m) => JSON.stringify(embeddingSetMemberToShard(m))).join("\n");
|
|
38368
|
-
files.set("embedding_set_members.jsonl",
|
|
39708
|
+
files.set("embedding_set_members.jsonl", encoder5.encode(membersJsonl));
|
|
38369
39709
|
components4.push("embedding_set_members");
|
|
38370
39710
|
counts.embedding_set_members = scopedEmbMemberRows.length;
|
|
38371
39711
|
const embRows = await db.query(
|
|
@@ -38391,7 +39731,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38391
39731
|
(embedding) => exportedSetIds.has(embedding.embedding_set_id) && exportedNoteIds.has(embedding.note_id) && (memberEmbeddingIds.size === 0 || memberEmbeddingIds.has(embedding.id))
|
|
38392
39732
|
);
|
|
38393
39733
|
const embJsonl = scopedEmbRows.map((e) => JSON.stringify(embeddingToShard(e))).join("\n");
|
|
38394
|
-
files.set("embeddings.jsonl",
|
|
39734
|
+
files.set("embeddings.jsonl", encoder5.encode(embJsonl));
|
|
38395
39735
|
components4.push("embeddings");
|
|
38396
39736
|
counts.embeddings = scopedEmbRows.length;
|
|
38397
39737
|
}
|
|
@@ -38417,7 +39757,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38417
39757
|
freshness: jsonObject3(row.freshness_json) ?? { status: "unknown" },
|
|
38418
39758
|
created_at: iso2(row.created_at)
|
|
38419
39759
|
}));
|
|
38420
|
-
files.set("graph_sources.json",
|
|
39760
|
+
files.set("graph_sources.json", encoder5.encode(JSON.stringify(shardGraphSources)));
|
|
38421
39761
|
components4.push("graph_sources");
|
|
38422
39762
|
counts.graph_sources = shardGraphSources.length;
|
|
38423
39763
|
}
|
|
@@ -38433,7 +39773,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38433
39773
|
rank: row.rank,
|
|
38434
39774
|
metadata: jsonObject3(row.metadata_json)
|
|
38435
39775
|
})).join("\n");
|
|
38436
|
-
files.set("graph_edges.jsonl",
|
|
39776
|
+
files.set("graph_edges.jsonl", encoder5.encode(graphEdgesJsonl));
|
|
38437
39777
|
components4.push("graph_edges");
|
|
38438
39778
|
counts.graph_edges = scopedGraphEdgeRows.length;
|
|
38439
39779
|
}
|
|
@@ -38469,7 +39809,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38469
39809
|
})),
|
|
38470
39810
|
created_at: iso2(row.created_at)
|
|
38471
39811
|
}));
|
|
38472
|
-
files.set("communities.json",
|
|
39812
|
+
files.set("communities.json", encoder5.encode(JSON.stringify(shardCommunitySets)));
|
|
38473
39813
|
components4.push("communities");
|
|
38474
39814
|
counts.community_sets = shardCommunitySets.length;
|
|
38475
39815
|
counts.communities = scopedCommunityRows.length;
|
|
@@ -38485,7 +39825,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38485
39825
|
source_type: row.source_type,
|
|
38486
39826
|
metadata: jsonObject3(row.metadata_json)
|
|
38487
39827
|
})).join("\n");
|
|
38488
|
-
files.set("community_assignments.jsonl",
|
|
39828
|
+
files.set("community_assignments.jsonl", encoder5.encode(assignmentsJsonl));
|
|
38489
39829
|
components4.push("community_assignments");
|
|
38490
39830
|
counts.community_assignments = scopedAssignmentRows.length;
|
|
38491
39831
|
}
|
|
@@ -38508,10 +39848,10 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38508
39848
|
const coreTags = [...tagsByName.values()].sort(
|
|
38509
39849
|
(left, right) => left.name.localeCompare(right.name)
|
|
38510
39850
|
);
|
|
38511
|
-
files.set("tags.json",
|
|
39851
|
+
files.set("tags.json", encoder5.encode(JSON.stringify(coreTags)));
|
|
38512
39852
|
components4.splice(0, components4.length, ...CORE_V1_COMPONENTS);
|
|
38513
|
-
for (const
|
|
38514
|
-
if (!CORE_V1_COMPONENTS.includes(
|
|
39853
|
+
for (const key3 of Object.keys(counts)) {
|
|
39854
|
+
if (!CORE_V1_COMPONENTS.includes(key3)) delete counts[key3];
|
|
38515
39855
|
}
|
|
38516
39856
|
Object.assign(counts, {
|
|
38517
39857
|
notes: shardNotes.length,
|
|
@@ -38548,7 +39888,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38548
39888
|
...!coreV1 ? { migrated_from: null } : {},
|
|
38549
39889
|
...!coreV1 && layout ? { layout } : {}
|
|
38550
39890
|
};
|
|
38551
|
-
files.set("manifest.json",
|
|
39891
|
+
files.set("manifest.json", encoder5.encode(JSON.stringify(manifest, null, 2)));
|
|
38552
39892
|
if (options?.includeBlobs && options.blobStore) {
|
|
38553
39893
|
const packed = /* @__PURE__ */ new Set();
|
|
38554
39894
|
for (const row of attachmentRows.rows) {
|
|
@@ -38573,14 +39913,14 @@ init_geometry_buffer();
|
|
|
38573
39913
|
|
|
38574
39914
|
// src/shard/parse.ts
|
|
38575
39915
|
init_geometry_buffer();
|
|
38576
|
-
var
|
|
39916
|
+
var decoder4 = new TextDecoder();
|
|
38577
39917
|
function parseJsonlBytes(data) {
|
|
38578
39918
|
if (!data || data.byteLength === 0) return [];
|
|
38579
|
-
return
|
|
39919
|
+
return decoder4.decode(data).split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
38580
39920
|
}
|
|
38581
39921
|
function parseJsonArrayBytes(data) {
|
|
38582
39922
|
if (!data || data.byteLength === 0) return [];
|
|
38583
|
-
return JSON.parse(
|
|
39923
|
+
return JSON.parse(decoder4.decode(data));
|
|
38584
39924
|
}
|
|
38585
39925
|
|
|
38586
39926
|
// src/shard/blob-staging.ts
|
|
@@ -38644,8 +39984,8 @@ async function promoteBlobs(blobStore, blobs) {
|
|
|
38644
39984
|
init_geometry_buffer();
|
|
38645
39985
|
function instant(value) {
|
|
38646
39986
|
if (value === null || value === void 0) return Number.NEGATIVE_INFINITY;
|
|
38647
|
-
const
|
|
38648
|
-
return Number.isNaN(
|
|
39987
|
+
const timestamp4 = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
39988
|
+
return Number.isNaN(timestamp4) ? Number.NEGATIVE_INFINITY : timestamp4;
|
|
38649
39989
|
}
|
|
38650
39990
|
function shouldApplyReplacement(existing, incoming) {
|
|
38651
39991
|
const existingDeleted = instant(existing.deleted_at);
|
|
@@ -39005,7 +40345,7 @@ async function importNativeFullV1(db, data, options = {}) {
|
|
|
39005
40345
|
}
|
|
39006
40346
|
|
|
39007
40347
|
// src/shard/shard-import.ts
|
|
39008
|
-
var
|
|
40348
|
+
var decoder5 = new TextDecoder();
|
|
39009
40349
|
var DEFAULT_BATCH_SIZE = 250;
|
|
39010
40350
|
function emptyCounts2() {
|
|
39011
40351
|
return {
|
|
@@ -39142,7 +40482,7 @@ async function importShard(db, data, options) {
|
|
|
39142
40482
|
}
|
|
39143
40483
|
let manifest;
|
|
39144
40484
|
try {
|
|
39145
|
-
manifest = JSON.parse(
|
|
40485
|
+
manifest = JSON.parse(decoder5.decode(manifestData));
|
|
39146
40486
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
39147
40487
|
throw new Error("manifest must be a JSON object");
|
|
39148
40488
|
}
|
|
@@ -39446,11 +40786,11 @@ async function importShard(db, data, options) {
|
|
|
39446
40786
|
}
|
|
39447
40787
|
}
|
|
39448
40788
|
}
|
|
39449
|
-
const skipExisting = async (
|
|
40789
|
+
const skipExisting = async (key3, sql, params) => {
|
|
39450
40790
|
if (strategy !== "skip") return false;
|
|
39451
40791
|
const existing = await tx.query(sql, params);
|
|
39452
40792
|
if (existing.rows.length === 0) return false;
|
|
39453
|
-
skipped[
|
|
40793
|
+
skipped[key3] = (skipped[key3] ?? 0) + 1;
|
|
39454
40794
|
return true;
|
|
39455
40795
|
};
|
|
39456
40796
|
const storePresence = async (component, recordId, record) => {
|
|
@@ -40374,8 +41714,8 @@ function slugifyServerEmbeddingSet(value) {
|
|
|
40374
41714
|
|
|
40375
41715
|
// src/shard/full-v1-store.ts
|
|
40376
41716
|
init_geometry_buffer();
|
|
40377
|
-
var
|
|
40378
|
-
var
|
|
41717
|
+
var decoder6 = new TextDecoder();
|
|
41718
|
+
var encoder6 = new TextEncoder();
|
|
40379
41719
|
function emptyCounts3() {
|
|
40380
41720
|
return {
|
|
40381
41721
|
notes: 0,
|
|
@@ -40429,12 +41769,12 @@ function componentRecords(component, bytes) {
|
|
|
40429
41769
|
function canonicalJson4(value) {
|
|
40430
41770
|
if (Array.isArray(value)) return `[${value.map(canonicalJson4).join(",")}]`;
|
|
40431
41771
|
if (value && typeof value === "object") {
|
|
40432
|
-
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([
|
|
41772
|
+
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson4(item)}`).join(",")}}`;
|
|
40433
41773
|
}
|
|
40434
41774
|
return JSON.stringify(value);
|
|
40435
41775
|
}
|
|
40436
41776
|
function encodeComponentRecords(component, records) {
|
|
40437
|
-
return
|
|
41777
|
+
return encoder6.encode(FULL_V1_COMPONENT_FILES[component].encoding === "json-array" ? JSON.stringify(records) : records.map((record) => JSON.stringify(record)).join("\n"));
|
|
40438
41778
|
}
|
|
40439
41779
|
function attachmentBlobReferences(files) {
|
|
40440
41780
|
const refs = /* @__PURE__ */ new Map();
|
|
@@ -40471,7 +41811,7 @@ async function importFullV1Snapshot(db, data, options) {
|
|
|
40471
41811
|
files = unpackTarGz(bytes);
|
|
40472
41812
|
const manifestBytes = files.get("manifest.json");
|
|
40473
41813
|
if (!manifestBytes) throw new Error("Missing manifest");
|
|
40474
|
-
const parsed2 = JSON.parse(
|
|
41814
|
+
const parsed2 = JSON.parse(decoder6.decode(manifestBytes));
|
|
40475
41815
|
if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2)) {
|
|
40476
41816
|
throw new Error("Manifest is not an object");
|
|
40477
41817
|
}
|
|
@@ -40725,7 +42065,7 @@ async function exportFullV1Snapshot(db, blobStore) {
|
|
|
40725
42065
|
name: "fortemi-react-full-v1-store",
|
|
40726
42066
|
version: manifest.producer?.version ?? "unknown"
|
|
40727
42067
|
};
|
|
40728
|
-
files.set("manifest.json",
|
|
42068
|
+
files.set("manifest.json", encoder6.encode(JSON.stringify(manifest, null, 2)));
|
|
40729
42069
|
files.delete("signature.json");
|
|
40730
42070
|
blobRefs = attachmentBlobReferences(files);
|
|
40731
42071
|
} else {
|
|
@@ -40752,7 +42092,7 @@ async function exportFullV1Snapshot(db, blobStore) {
|
|
|
40752
42092
|
|
|
40753
42093
|
// src/shard/shard-reader.ts
|
|
40754
42094
|
init_geometry_buffer();
|
|
40755
|
-
var
|
|
42095
|
+
var decoder7 = new TextDecoder();
|
|
40756
42096
|
function assertSafeComponentName(filename) {
|
|
40757
42097
|
if (filename.length === 0 || filename.startsWith("/") || filename.includes("\\") || filename.includes("\0") || filename.includes(":") || filename.split("/").some((segment) => segment === "..")) {
|
|
40758
42098
|
throw new Error(`Refusing to read unsafe shard component path: ${JSON.stringify(filename)}`);
|
|
@@ -40854,7 +42194,7 @@ async function resolveStore(source, maxComponentBytes) {
|
|
|
40854
42194
|
const files = unpackTarGz(bytes);
|
|
40855
42195
|
const manifestBytes = files.get("manifest.json");
|
|
40856
42196
|
if (!manifestBytes) throw new Error("Missing manifest.json in shard archive");
|
|
40857
|
-
const manifest = JSON.parse(
|
|
42197
|
+
const manifest = JSON.parse(decoder7.decode(manifestBytes));
|
|
40858
42198
|
return new PackedComponentStore(files, manifest);
|
|
40859
42199
|
}
|
|
40860
42200
|
function tokenize(query) {
|
|
@@ -40991,14 +42331,14 @@ var ShardReaderImpl = class {
|
|
|
40991
42331
|
weights: { ...DEFAULT_WEIGHTS, ...options.weights }
|
|
40992
42332
|
});
|
|
40993
42333
|
}
|
|
40994
|
-
cacheMatches(
|
|
40995
|
-
this.matchCache.delete(
|
|
40996
|
-
this.matchCache.set(
|
|
42334
|
+
cacheMatches(key3, notes) {
|
|
42335
|
+
this.matchCache.delete(key3);
|
|
42336
|
+
this.matchCache.set(key3, notes);
|
|
40997
42337
|
let total = 0;
|
|
40998
42338
|
for (const set of this.matchCache.values()) total += set.length;
|
|
40999
42339
|
while (total > this.maxCachedMatches && this.matchCache.size > 1) {
|
|
41000
42340
|
const oldest = this.matchCache.keys().next().value;
|
|
41001
|
-
if (oldest === void 0 || oldest ===
|
|
42341
|
+
if (oldest === void 0 || oldest === key3) break;
|
|
41002
42342
|
total -= this.matchCache.get(oldest)?.length ?? 0;
|
|
41003
42343
|
this.matchCache.delete(oldest);
|
|
41004
42344
|
}
|
|
@@ -41008,12 +42348,12 @@ var ShardReaderImpl = class {
|
|
|
41008
42348
|
const weights = { ...DEFAULT_WEIGHTS, ...options.weights };
|
|
41009
42349
|
const offset = options.offset ?? 0;
|
|
41010
42350
|
const limit = options.limit ?? Number.MAX_SAFE_INTEGER;
|
|
41011
|
-
const
|
|
41012
|
-
let matched = this.matchCache.get(
|
|
42351
|
+
const key3 = this.matchKey(query, options);
|
|
42352
|
+
let matched = this.matchCache.get(key3);
|
|
41013
42353
|
let fetchedClusters = 0;
|
|
41014
42354
|
if (matched) {
|
|
41015
|
-
this.matchCache.delete(
|
|
41016
|
-
this.matchCache.set(
|
|
42355
|
+
this.matchCache.delete(key3);
|
|
42356
|
+
this.matchCache.set(key3, matched);
|
|
41017
42357
|
} else {
|
|
41018
42358
|
const { notes, fetched } = await this.loadAllNotes();
|
|
41019
42359
|
fetchedClusters = fetched;
|
|
@@ -41021,7 +42361,7 @@ var ShardReaderImpl = class {
|
|
|
41021
42361
|
if (tokens.length > 0 && options.rank !== false) {
|
|
41022
42362
|
matched = [...matched].sort((a, b) => rankNote(b, tokens, weights) - rankNote(a, tokens, weights));
|
|
41023
42363
|
}
|
|
41024
|
-
this.cacheMatches(
|
|
42364
|
+
this.cacheMatches(key3, matched);
|
|
41025
42365
|
}
|
|
41026
42366
|
const page = matched.slice(offset, offset + limit);
|
|
41027
42367
|
const result = {
|
|
@@ -41140,7 +42480,7 @@ async function openShard(source, options = {}) {
|
|
|
41140
42480
|
|
|
41141
42481
|
// src/shard/semantic-providers.ts
|
|
41142
42482
|
init_geometry_buffer();
|
|
41143
|
-
var
|
|
42483
|
+
var decoder8 = new TextDecoder();
|
|
41144
42484
|
function cosine(a, b) {
|
|
41145
42485
|
let dot = 0;
|
|
41146
42486
|
let normA = 0;
|
|
@@ -41164,7 +42504,7 @@ function createCosineSemanticProvider(options) {
|
|
|
41164
42504
|
vectors = [];
|
|
41165
42505
|
return;
|
|
41166
42506
|
}
|
|
41167
|
-
vectors =
|
|
42507
|
+
vectors = decoder8.decode(bytes).split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
41168
42508
|
},
|
|
41169
42509
|
async search(query, k) {
|
|
41170
42510
|
const queryVector = await options.embedQuery(query);
|
|
@@ -42700,14 +44040,14 @@ function matchSetCacheKey(q, options) {
|
|
|
42700
44040
|
weights: { ...DEFAULT_QUERY_WEIGHTS, ...options.weights }
|
|
42701
44041
|
});
|
|
42702
44042
|
}
|
|
42703
|
-
function cacheMatchEntries(runtime,
|
|
42704
|
-
runtime.matchCache.delete(
|
|
42705
|
-
runtime.matchCache.set(
|
|
44043
|
+
function cacheMatchEntries(runtime, key3, entries) {
|
|
44044
|
+
runtime.matchCache.delete(key3);
|
|
44045
|
+
runtime.matchCache.set(key3, entries);
|
|
42706
44046
|
let total = 0;
|
|
42707
44047
|
for (const set of runtime.matchCache.values()) total += set.length;
|
|
42708
44048
|
while (total > runtime.maxCachedMatches && runtime.matchCache.size > 1) {
|
|
42709
44049
|
const oldest = runtime.matchCache.keys().next().value;
|
|
42710
|
-
if (oldest === void 0 || oldest ===
|
|
44050
|
+
if (oldest === void 0 || oldest === key3) break;
|
|
42711
44051
|
total -= runtime.matchCache.get(oldest)?.length ?? 0;
|
|
42712
44052
|
runtime.matchCache.delete(oldest);
|
|
42713
44053
|
}
|
|
@@ -42720,15 +44060,15 @@ function getPartsForRange(manifest, offset, limit) {
|
|
|
42720
44060
|
return manifest.parts.filter((part) => part.count > 0 && part.offset < end && part.offset + part.count > offset);
|
|
42721
44061
|
}
|
|
42722
44062
|
async function loadChunkPart(runtime, part) {
|
|
42723
|
-
const
|
|
42724
|
-
const cached = runtime.partCache.get(
|
|
44063
|
+
const key3 = chunkPartCacheKey(part);
|
|
44064
|
+
const cached = runtime.partCache.get(key3);
|
|
42725
44065
|
if (cached) {
|
|
42726
|
-
runtime.partCache.delete(
|
|
42727
|
-
runtime.partCache.set(
|
|
44066
|
+
runtime.partCache.delete(key3);
|
|
44067
|
+
runtime.partCache.set(key3, cached);
|
|
42728
44068
|
return { part: cached, fetched: false };
|
|
42729
44069
|
}
|
|
42730
44070
|
const parsed = assertAiwgFortemiChunkPart(await runtime.loader(part, runtime.manifest), part, runtime.manifest);
|
|
42731
|
-
runtime.partCache.set(
|
|
44071
|
+
runtime.partCache.set(key3, parsed);
|
|
42732
44072
|
while (runtime.partCache.size > runtime.maxCachedParts) {
|
|
42733
44073
|
const oldest = runtime.partCache.keys().next().value;
|
|
42734
44074
|
if (oldest === void 0) break;
|
|
@@ -43153,10 +44493,10 @@ function aiwgFortemiIndexToCommunityGraph(index, options = {}) {
|
|
|
43153
44493
|
const kind = relationship.type;
|
|
43154
44494
|
const configuredWeight = Object.prototype.hasOwnProperty.call(relationshipWeights, kind) ? relationshipWeights[kind] : void 0;
|
|
43155
44495
|
const baseWeight = typeof configuredWeight === "number" && Number.isFinite(configuredWeight) ? configuredWeight : 1;
|
|
43156
|
-
const
|
|
43157
|
-
const existing = edgeCounts.get(
|
|
44496
|
+
const key3 = `${item.id}\0${relationship.target_id}\0${kind}`;
|
|
44497
|
+
const existing = edgeCounts.get(key3);
|
|
43158
44498
|
if (existing) existing.weight += baseWeight;
|
|
43159
|
-
else edgeCounts.set(
|
|
44499
|
+
else edgeCounts.set(key3, { source: item.id, target: relationship.target_id, kind, weight: baseWeight });
|
|
43160
44500
|
}
|
|
43161
44501
|
}
|
|
43162
44502
|
const communities = /* @__PURE__ */ new Map();
|
|
@@ -43896,7 +45236,7 @@ function getAiwgFortemiIndexExportSchema() {
|
|
|
43896
45236
|
}
|
|
43897
45237
|
function getAjv() {
|
|
43898
45238
|
if (!ajvInstance) {
|
|
43899
|
-
ajvInstance = new
|
|
45239
|
+
ajvInstance = new Ajv20206({
|
|
43900
45240
|
allErrors: true,
|
|
43901
45241
|
strict: false,
|
|
43902
45242
|
validateFormats: false
|
|
@@ -43941,7 +45281,7 @@ function getProjectedRecordValidator() {
|
|
|
43941
45281
|
return projectedRecordValidator;
|
|
43942
45282
|
}
|
|
43943
45283
|
function validateAiwgFortemiIndexExportSchema(value) {
|
|
43944
|
-
const
|
|
45284
|
+
const validate4 = getExportValidator();
|
|
43945
45285
|
const schemaValue = value && typeof value === "object" && Array.isArray(value.items) ? {
|
|
43946
45286
|
...value,
|
|
43947
45287
|
items: value.items.map((item) => {
|
|
@@ -43951,18 +45291,18 @@ function validateAiwgFortemiIndexExportSchema(value) {
|
|
|
43951
45291
|
return schemaRecord;
|
|
43952
45292
|
})
|
|
43953
45293
|
} : value;
|
|
43954
|
-
const valid =
|
|
43955
|
-
return { valid, errors: formatErrors2(
|
|
45294
|
+
const valid = validate4(schemaValue);
|
|
45295
|
+
return { valid, errors: formatErrors2(validate4.errors) };
|
|
43956
45296
|
}
|
|
43957
45297
|
function validateAiwgFortemiProjectedRecordSchema(value) {
|
|
43958
|
-
const
|
|
43959
|
-
const valid =
|
|
43960
|
-
return { valid, errors: formatErrors2(
|
|
45298
|
+
const validate4 = getProjectedRecordValidator();
|
|
45299
|
+
const valid = validate4(value);
|
|
45300
|
+
return { valid, errors: formatErrors2(validate4.errors) };
|
|
43961
45301
|
}
|
|
43962
45302
|
|
|
43963
45303
|
// src/aiwg-index-full-shard.ts
|
|
43964
45304
|
init_geometry_buffer();
|
|
43965
|
-
var
|
|
45305
|
+
var encoder7 = new TextEncoder();
|
|
43966
45306
|
var UUID_NAMESPACE = "7ab5d1f8-29d2-5e35-9e2f-3a45de171a9e";
|
|
43967
45307
|
function uuid5(kind, id) {
|
|
43968
45308
|
return v5(`${kind}:${id}`, UUID_NAMESPACE);
|
|
@@ -43970,7 +45310,7 @@ function uuid5(kind, id) {
|
|
|
43970
45310
|
function own(value, field) {
|
|
43971
45311
|
return Object.prototype.hasOwnProperty.call(value, field);
|
|
43972
45312
|
}
|
|
43973
|
-
function
|
|
45313
|
+
function timestamp3(value) {
|
|
43974
45314
|
if (!value || Number.isNaN(Date.parse(value))) return void 0;
|
|
43975
45315
|
return new Date(value).toISOString();
|
|
43976
45316
|
}
|
|
@@ -43978,7 +45318,7 @@ function addLoss(losses, code, message, details = {}) {
|
|
|
43978
45318
|
losses.push({ code, message, ...details });
|
|
43979
45319
|
}
|
|
43980
45320
|
function encode(values, encoding) {
|
|
43981
|
-
return
|
|
45321
|
+
return encoder7.encode(encoding === "json-array" ? JSON.stringify(values) : values.map((value) => JSON.stringify(value)).join("\n"));
|
|
43982
45322
|
}
|
|
43983
45323
|
function noteTitle(record, losses) {
|
|
43984
45324
|
if (own(record, "title")) return record.title ?? null;
|
|
@@ -44043,7 +45383,7 @@ function noteContent(record, losses) {
|
|
|
44043
45383
|
return "";
|
|
44044
45384
|
}
|
|
44045
45385
|
function createdAt(record, losses) {
|
|
44046
|
-
const source =
|
|
45386
|
+
const source = timestamp3(record.source.updated_at);
|
|
44047
45387
|
if (source) return source;
|
|
44048
45388
|
addLoss(
|
|
44049
45389
|
losses,
|
|
@@ -44073,7 +45413,7 @@ function schemeName(concept) {
|
|
|
44073
45413
|
}
|
|
44074
45414
|
async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
44075
45415
|
const losses = [];
|
|
44076
|
-
const exportedAt =
|
|
45416
|
+
const exportedAt = timestamp3(options.createdAt) ?? new Date(index.generated_at).toISOString();
|
|
44077
45417
|
const records = [...index.items].sort((a, b) => a.id.localeCompare(b.id));
|
|
44078
45418
|
const noteIds = new Map(records.map((record) => [record.id, uuid5("record", record.id)]));
|
|
44079
45419
|
const rows = /* @__PURE__ */ new Map();
|
|
@@ -44146,7 +45486,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44146
45486
|
tags: recordTags,
|
|
44147
45487
|
attachments: []
|
|
44148
45488
|
});
|
|
44149
|
-
const hash = await sha256Hex(
|
|
45489
|
+
const hash = await sha256Hex(encoder7.encode(content));
|
|
44150
45490
|
rows.get("note_originals").push({
|
|
44151
45491
|
id: uuid5("note-original", record.id),
|
|
44152
45492
|
note_id: noteId,
|
|
@@ -44168,9 +45508,9 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44168
45508
|
for (const record of records) {
|
|
44169
45509
|
for (const [position, relationship] of record.relationships.entries()) {
|
|
44170
45510
|
const target = noteIds.get(relationship.target_id) ?? null;
|
|
44171
|
-
const
|
|
45511
|
+
const key3 = `${record.id}\0${position}\0${relationship.type}\0${relationship.target_id}`;
|
|
44172
45512
|
rows.get("links").push({
|
|
44173
|
-
id: uuid5("relationship",
|
|
45513
|
+
id: uuid5("relationship", key3),
|
|
44174
45514
|
from_note_id: noteIds.get(record.id),
|
|
44175
45515
|
to_note_id: target,
|
|
44176
45516
|
to_url: target ? null : `aiwg://record/${encodeURIComponent(relationship.target_id)}`,
|
|
@@ -44238,7 +45578,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44238
45578
|
metric: null,
|
|
44239
45579
|
algorithm: null,
|
|
44240
45580
|
parameters: null,
|
|
44241
|
-
input_hash: `sha256:${await sha256Hex(
|
|
45581
|
+
input_hash: `sha256:${await sha256Hex(encoder7.encode(JSON.stringify(relationshipInput)))}`,
|
|
44242
45582
|
freshness: { status: "fresh", checked_at: exportedAt },
|
|
44243
45583
|
created_at: exportedAt
|
|
44244
45584
|
});
|
|
@@ -44327,7 +45667,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44327
45667
|
action: "omit"
|
|
44328
45668
|
}
|
|
44329
45669
|
);
|
|
44330
|
-
const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((
|
|
45670
|
+
const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((key3) => key3 !== "domain");
|
|
44331
45671
|
if (unmappedConceptMetadata.length > 0) addLoss(
|
|
44332
45672
|
losses,
|
|
44333
45673
|
"aiwg-skos-metadata-unmapped",
|
|
@@ -44470,7 +45810,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44470
45810
|
}
|
|
44471
45811
|
for (const record of records) {
|
|
44472
45812
|
for (const [position, event] of (record.provenance_events ?? []).entries()) {
|
|
44473
|
-
const start =
|
|
45813
|
+
const start = timestamp3(event.started_at);
|
|
44474
45814
|
if (!start) addLoss(
|
|
44475
45815
|
losses,
|
|
44476
45816
|
"aiwg-provenance-start-unavailable",
|
|
@@ -44490,7 +45830,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44490
45830
|
activity_type: event.activity,
|
|
44491
45831
|
model_name: event.agent ?? null,
|
|
44492
45832
|
started_at: start ?? new Date(record.updated_at).toISOString(),
|
|
44493
|
-
ended_at:
|
|
45833
|
+
ended_at: timestamp3(event.ended_at) ?? null,
|
|
44494
45834
|
metadata: {
|
|
44495
45835
|
source: event.source ?? null,
|
|
44496
45836
|
path: event.path ?? null,
|
|
@@ -44696,7 +46036,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44696
46036
|
checksums,
|
|
44697
46037
|
min_reader_version: "2.0.0"
|
|
44698
46038
|
};
|
|
44699
|
-
const manifestBytes =
|
|
46039
|
+
const manifestBytes = encoder7.encode(JSON.stringify(manifest, null, 2));
|
|
44700
46040
|
files.set("manifest.json", manifestBytes);
|
|
44701
46041
|
const validation = await validateFullV1ShardArchive(files);
|
|
44702
46042
|
if (!validation.valid) {
|
|
@@ -44976,7 +46316,7 @@ var RECORD_STORE_CAPABILITIES = {
|
|
|
44976
46316
|
sourceAddressedUpsert: true,
|
|
44977
46317
|
deletionReceipts: true,
|
|
44978
46318
|
typedMetadataPredicates: false,
|
|
44979
|
-
evidenceLocators:
|
|
46319
|
+
evidenceLocators: false,
|
|
44980
46320
|
fullTextSearch: false,
|
|
44981
46321
|
vectorSearch: false,
|
|
44982
46322
|
sqlJoins: false
|
|
@@ -45363,7 +46703,7 @@ var CanonicalNotesRepository = class {
|
|
|
45363
46703
|
* Bounded substring scan over title + revised content (case-insensitive).
|
|
45364
46704
|
* This is deliberately not ranked FTS — see `store.capabilities`.
|
|
45365
46705
|
*/
|
|
45366
|
-
async searchText(query, limit = 20) {
|
|
46706
|
+
async searchText(query, limit = 20, accept) {
|
|
45367
46707
|
const needle = query.toLowerCase();
|
|
45368
46708
|
const revised = new Map(
|
|
45369
46709
|
(await this.store.list("note_revised_current")).map((r) => [r.id, r.content])
|
|
@@ -45371,6 +46711,7 @@ var CanonicalNotesRepository = class {
|
|
|
45371
46711
|
const hits = [];
|
|
45372
46712
|
for (const note of await this.store.list("note")) {
|
|
45373
46713
|
if (note.deleted_at !== null) continue;
|
|
46714
|
+
if (accept && !accept(note)) continue;
|
|
45374
46715
|
const haystack = `${note.title ?? ""}
|
|
45375
46716
|
${revised.get(note.id) ?? ""}`.toLowerCase();
|
|
45376
46717
|
if (haystack.includes(needle)) {
|
|
@@ -45886,6 +47227,8 @@ function createRecordBackend(store, options = {}) {
|
|
|
45886
47227
|
// via importShardToRecords (record-shard.ts)
|
|
45887
47228
|
multiUser: false,
|
|
45888
47229
|
semantic: "none",
|
|
47230
|
+
typedMetadataPredicates: false,
|
|
47231
|
+
evidenceLocators: false,
|
|
45889
47232
|
startupCost: "instant"
|
|
45890
47233
|
},
|
|
45891
47234
|
async listNotes(o) {
|
|
@@ -45905,17 +47248,11 @@ function createRecordBackend(store, options = {}) {
|
|
|
45905
47248
|
return noteToBackend(view.note, view.tags);
|
|
45906
47249
|
},
|
|
45907
47250
|
async search(query, o) {
|
|
47251
|
+
validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
|
|
45908
47252
|
const offset = o?.offset ?? 0;
|
|
45909
47253
|
const limit = o?.limit ?? 20;
|
|
45910
|
-
let matched = await notes.searchText(query, offset + limit);
|
|
45911
|
-
if (o?.tags?.length) {
|
|
45912
|
-
const tags2 = await tagsByNote();
|
|
45913
|
-
matched = matched.filter((n) => o.tags.every((t) => (tags2.get(n.id) ?? []).includes(t)));
|
|
45914
|
-
}
|
|
45915
|
-
if (o?.source?.length) {
|
|
45916
|
-
matched = matched.filter((n) => o.source.includes(n.source));
|
|
45917
|
-
}
|
|
45918
47254
|
const tags = await tagsByNote();
|
|
47255
|
+
const matched = await notes.searchText(query, offset + limit, (n) => (!o?.tags?.length || o.tags.every((t) => (tags.get(n.id) ?? []).includes(t))) && (!o?.source?.length || o.source.includes(n.source)));
|
|
45919
47256
|
const hits = matched.slice(offset, offset + limit).map((n) => ({ note: noteToBackend(n, tags.get(n.id) ?? []) }));
|
|
45920
47257
|
return { hits, total: matched.length };
|
|
45921
47258
|
},
|
|
@@ -45973,8 +47310,8 @@ function createRecordBackend(store, options = {}) {
|
|
|
45973
47310
|
|
|
45974
47311
|
// src/records/record-shard.ts
|
|
45975
47312
|
init_geometry_buffer();
|
|
45976
|
-
var
|
|
45977
|
-
var
|
|
47313
|
+
var encoder8 = new TextEncoder();
|
|
47314
|
+
var decoder9 = new TextDecoder();
|
|
45978
47315
|
function emptyCounts4() {
|
|
45979
47316
|
return {
|
|
45980
47317
|
notes: 0,
|
|
@@ -46231,11 +47568,11 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
46231
47568
|
const slice = shardNotes.slice(offset, offset + clusterSize);
|
|
46232
47569
|
const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
|
|
46233
47570
|
clusters.push({ href, offset });
|
|
46234
|
-
files.set(href,
|
|
47571
|
+
files.set(href, encoder8.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
|
|
46235
47572
|
}
|
|
46236
47573
|
layout = { clusters: { notes: clusters } };
|
|
46237
47574
|
} else {
|
|
46238
|
-
files.set("notes.jsonl",
|
|
47575
|
+
files.set("notes.jsonl", encoder8.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
|
|
46239
47576
|
}
|
|
46240
47577
|
components4.push("notes");
|
|
46241
47578
|
counts.notes = shardNotes.length;
|
|
@@ -46263,7 +47600,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
46263
47600
|
note_count: mapped.note_count ?? 0
|
|
46264
47601
|
};
|
|
46265
47602
|
});
|
|
46266
|
-
files.set("collections.json",
|
|
47603
|
+
files.set("collections.json", encoder8.encode(JSON.stringify(shardCollections)));
|
|
46267
47604
|
components4.push("collections");
|
|
46268
47605
|
counts.collections = shardCollections.length;
|
|
46269
47606
|
const distinctTags = [...new Set(
|
|
@@ -46280,7 +47617,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
46280
47617
|
created_at: tagCreatedAt.get(name) ?? (/* @__PURE__ */ new Date(0)).toISOString()
|
|
46281
47618
|
}))
|
|
46282
47619
|
);
|
|
46283
|
-
files.set("tags.json",
|
|
47620
|
+
files.set("tags.json", encoder8.encode(JSON.stringify(shardTags)));
|
|
46284
47621
|
components4.push("tags");
|
|
46285
47622
|
counts.tags = shardTags.length;
|
|
46286
47623
|
const links = await store.list("link");
|
|
@@ -46302,7 +47639,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
46302
47639
|
}
|
|
46303
47640
|
return shard;
|
|
46304
47641
|
});
|
|
46305
|
-
files.set("links.jsonl",
|
|
47642
|
+
files.set("links.jsonl", encoder8.encode(shardLinks.map((l) => JSON.stringify(l)).join("\n")));
|
|
46306
47643
|
components4.push("links");
|
|
46307
47644
|
counts.links = shardLinks.length;
|
|
46308
47645
|
const checksums = {};
|
|
@@ -46432,7 +47769,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
46432
47769
|
);
|
|
46433
47770
|
}
|
|
46434
47771
|
}
|
|
46435
|
-
files.set("manifest.json",
|
|
47772
|
+
files.set("manifest.json", encoder8.encode(JSON.stringify(manifest, null, 2)));
|
|
46436
47773
|
if (options?.includeBlobs && options.blobStore) {
|
|
46437
47774
|
const packed = /* @__PURE__ */ new Set();
|
|
46438
47775
|
for (const checksum of exportedBlobChecksums) {
|
|
@@ -46512,7 +47849,7 @@ async function importShardToRecords(store, data, options) {
|
|
|
46512
47849
|
}
|
|
46513
47850
|
let manifest;
|
|
46514
47851
|
try {
|
|
46515
|
-
manifest = JSON.parse(
|
|
47852
|
+
manifest = JSON.parse(decoder9.decode(manifestData));
|
|
46516
47853
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
46517
47854
|
throw new Error("manifest must be a JSON object");
|
|
46518
47855
|
}
|
|
@@ -46649,8 +47986,8 @@ async function importShardToRecords(store, data, options) {
|
|
|
46649
47986
|
for (const component of manifest.components ?? []) {
|
|
46650
47987
|
if (UNSUPPORTED_COMPONENTS.includes(component)) {
|
|
46651
47988
|
const count2 = manifest.counts?.[component];
|
|
46652
|
-
const
|
|
46653
|
-
skipped[
|
|
47989
|
+
const key3 = component === "communities" ? "communities" : component;
|
|
47990
|
+
skipped[key3] = (skipped[key3] ?? 0) + (typeof count2 === "number" ? count2 : 0);
|
|
46654
47991
|
warnings.push(
|
|
46655
47992
|
`Shard component '${component}' is not supported by the canonical record tier and was skipped. Import into a PGlite-backed store to preserve it.`
|
|
46656
47993
|
);
|
|
@@ -46818,7 +48155,7 @@ async function importShardToRecords(store, data, options) {
|
|
|
46818
48155
|
id: existingOriginal?.id ?? generateId(),
|
|
46819
48156
|
note_id: note.id,
|
|
46820
48157
|
content: note.original_content,
|
|
46821
|
-
content_hash: computeHash(
|
|
48158
|
+
content_hash: computeHash(encoder8.encode(note.original_content)),
|
|
46822
48159
|
created_at: createdAt2
|
|
46823
48160
|
};
|
|
46824
48161
|
mutations.push({ op: "put", collection: "note_original", record: originalRecord });
|
|
@@ -47125,7 +48462,7 @@ async function upsertRecordStoreSources(store, items, options = {}) {
|
|
|
47125
48462
|
const requestDigest = sourceRequestDigest(items, options);
|
|
47126
48463
|
const batchId = options.batchId ?? deriveSourceBatchId(requestDigest);
|
|
47127
48464
|
const batchReason = batchId.length === 0 || batchId.length > 200 ? "invalid_batch_metadata" : JSON.stringify(options.checkpoint ?? {}).length > 65536 ? "checkpoint_too_large" : void 0;
|
|
47128
|
-
const validation =
|
|
48465
|
+
const validation = validate3(items, options.maxItems ?? 500, batchReason);
|
|
47129
48466
|
if (validation) return finish2(importRunId, batchId, options.dryRun === true, "rejected", validation, options.checkpoint);
|
|
47130
48467
|
const batches = await store.list("source_import_batch");
|
|
47131
48468
|
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);
|
|
@@ -47309,7 +48646,7 @@ function addUpdateMutations(mutations, item, identity, note, current, original,
|
|
|
47309
48646
|
mutations.push({ op: "put", collection: "note_revision", record: revision });
|
|
47310
48647
|
}
|
|
47311
48648
|
}
|
|
47312
|
-
function
|
|
48649
|
+
function validate3(items, maxItems, initialReason) {
|
|
47313
48650
|
let reason = initialReason ?? (items.length === 0 || items.length > maxItems ? "batch_size_out_of_bounds" : null);
|
|
47314
48651
|
const seen = /* @__PURE__ */ new Set();
|
|
47315
48652
|
const stableIds = /* @__PURE__ */ new Set();
|
|
@@ -47318,9 +48655,9 @@ function validate2(items, maxItems, initialReason) {
|
|
|
47318
48655
|
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";
|
|
47319
48656
|
if ((item.format ?? "markdown").length > 100 || (item.title?.length ?? 0) > 2e3 || JSON.stringify(item.metadata ?? {}).length > 262144) reason ??= "invalid_item";
|
|
47320
48657
|
if (item.content_digest && item.content_digest !== sourceContentDigest(item.content)) reason ??= "content_digest_mismatch";
|
|
47321
|
-
const
|
|
47322
|
-
if (seen.has(
|
|
47323
|
-
seen.add(
|
|
48658
|
+
const key3 = `${item.source.tenant_id}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
|
|
48659
|
+
if (seen.has(key3)) reason ??= "duplicate_external_id_in_batch";
|
|
48660
|
+
seen.add(key3);
|
|
47324
48661
|
if (item.source.caller_stable_id && stableIds.has(item.source.caller_stable_id)) reason ??= "caller_stable_id_conflict";
|
|
47325
48662
|
if (item.source.caller_stable_id) stableIds.add(item.source.caller_stable_id);
|
|
47326
48663
|
}
|
|
@@ -47452,7 +48789,7 @@ async function purgeRecordStoreGraph(store, selector, operationKey) {
|
|
|
47452
48789
|
}
|
|
47453
48790
|
|
|
47454
48791
|
// src/index.ts
|
|
47455
|
-
var VERSION = "2026.9.
|
|
48792
|
+
var VERSION = "2026.9.6";
|
|
47456
48793
|
/*! Bundled license information:
|
|
47457
48794
|
|
|
47458
48795
|
ieee754/index.js:
|
|
@@ -47467,6 +48804,6 @@ buffer/index.js:
|
|
|
47467
48804
|
*)
|
|
47468
48805
|
*/
|
|
47469
48806
|
|
|
47470
|
-
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, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, 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, exportFullV1Snapshot, 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, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetExecutionCapabilitiesFromWire, 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, validateDatasetExecutionRequest, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
48807
|
+
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, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, bindSearchEvidence, 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, createSearchEvidenceSet, 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, exportFullV1Snapshot, 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, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, mergeSearchEvidenceSets, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetExecutionCapabilitiesFromWire, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, parseSearchEvidenceLocator, parseSearchEvidenceSet, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, resolveSearchEvidence, 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, validateDatasetExecutionRequest, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
47471
48808
|
//# sourceMappingURL=index.js.map
|
|
47472
48809
|
//# sourceMappingURL=index.js.map
|