@fortemi/core 2026.7.7 → 2026.7.8
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 +235 -98
- package/dist/index.js +794 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6541,13 +6541,13 @@ var OpenAICompatibleProvider = class {
|
|
|
6541
6541
|
throw new Error("Streaming not supported: response body is null");
|
|
6542
6542
|
}
|
|
6543
6543
|
const reader = response.body.getReader();
|
|
6544
|
-
const
|
|
6544
|
+
const decoder7 = new TextDecoder();
|
|
6545
6545
|
let buffer = "";
|
|
6546
6546
|
try {
|
|
6547
6547
|
while (true) {
|
|
6548
6548
|
const { done, value } = await reader.read();
|
|
6549
6549
|
if (done) break;
|
|
6550
|
-
buffer +=
|
|
6550
|
+
buffer += decoder7.decode(value, { stream: true });
|
|
6551
6551
|
const lines = buffer.split("\n");
|
|
6552
6552
|
buffer = lines.pop() ?? "";
|
|
6553
6553
|
for (const line of lines) {
|
|
@@ -13422,6 +13422,8 @@ var CanonicalNotesRepository = class {
|
|
|
13422
13422
|
await this.store.put("note", {
|
|
13423
13423
|
...note,
|
|
13424
13424
|
title: input.title !== void 0 ? input.title : note.title,
|
|
13425
|
+
format: input.format ?? note.format,
|
|
13426
|
+
visibility: input.visibility ?? note.visibility,
|
|
13425
13427
|
is_starred: input.is_starred ?? note.is_starred,
|
|
13426
13428
|
is_pinned: input.is_pinned ?? note.is_pinned,
|
|
13427
13429
|
is_archived: input.is_archived ?? note.is_archived,
|
|
@@ -13718,9 +13720,797 @@ async function dropAttachmentProjection(db) {
|
|
|
13718
13720
|
await db.query(`DELETE FROM attachment_blob`);
|
|
13719
13721
|
}
|
|
13720
13722
|
|
|
13723
|
+
// src/records/record-projection.ts
|
|
13724
|
+
async function projectNotes(db, store) {
|
|
13725
|
+
const [noteRows, originals, revised, tags, links, collections, memberships] = await Promise.all([
|
|
13726
|
+
store.list("note"),
|
|
13727
|
+
store.list("note_original"),
|
|
13728
|
+
store.list("note_revised_current"),
|
|
13729
|
+
store.list("note_tag"),
|
|
13730
|
+
store.list("link"),
|
|
13731
|
+
store.list("collection"),
|
|
13732
|
+
store.list("collection_note")
|
|
13733
|
+
]);
|
|
13734
|
+
for (const c of collections) {
|
|
13735
|
+
await db.query(
|
|
13736
|
+
`INSERT INTO collection (id, name, description, created_at, updated_at, deleted_at)
|
|
13737
|
+
VALUES ($1, $2, $3, $4, $5, $6)
|
|
13738
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
13739
|
+
name = EXCLUDED.name,
|
|
13740
|
+
description = EXCLUDED.description,
|
|
13741
|
+
updated_at = EXCLUDED.updated_at,
|
|
13742
|
+
deleted_at = EXCLUDED.deleted_at`,
|
|
13743
|
+
[c.id, c.name, c.description, c.created_at, c.updated_at, c.deleted_at]
|
|
13744
|
+
);
|
|
13745
|
+
}
|
|
13746
|
+
for (const n of noteRows) {
|
|
13747
|
+
await db.query(
|
|
13748
|
+
`INSERT INTO note (
|
|
13749
|
+
id, archive_id, title, format, source, visibility, revision_mode,
|
|
13750
|
+
is_starred, is_pinned, is_archived, created_at, updated_at, deleted_at
|
|
13751
|
+
)
|
|
13752
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
|
13753
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
13754
|
+
archive_id = EXCLUDED.archive_id,
|
|
13755
|
+
title = EXCLUDED.title,
|
|
13756
|
+
format = EXCLUDED.format,
|
|
13757
|
+
source = EXCLUDED.source,
|
|
13758
|
+
visibility = EXCLUDED.visibility,
|
|
13759
|
+
revision_mode = EXCLUDED.revision_mode,
|
|
13760
|
+
is_starred = EXCLUDED.is_starred,
|
|
13761
|
+
is_pinned = EXCLUDED.is_pinned,
|
|
13762
|
+
is_archived = EXCLUDED.is_archived,
|
|
13763
|
+
updated_at = EXCLUDED.updated_at,
|
|
13764
|
+
deleted_at = EXCLUDED.deleted_at`,
|
|
13765
|
+
[
|
|
13766
|
+
n.id,
|
|
13767
|
+
n.archive_id,
|
|
13768
|
+
n.title,
|
|
13769
|
+
n.format,
|
|
13770
|
+
n.source,
|
|
13771
|
+
n.visibility,
|
|
13772
|
+
n.revision_mode,
|
|
13773
|
+
n.is_starred,
|
|
13774
|
+
n.is_pinned,
|
|
13775
|
+
n.is_archived,
|
|
13776
|
+
n.created_at,
|
|
13777
|
+
n.updated_at,
|
|
13778
|
+
n.deleted_at
|
|
13779
|
+
]
|
|
13780
|
+
);
|
|
13781
|
+
}
|
|
13782
|
+
for (const o of originals) {
|
|
13783
|
+
await db.query(
|
|
13784
|
+
`INSERT INTO note_original (id, note_id, content, content_hash, created_at)
|
|
13785
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
13786
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
13787
|
+
content = EXCLUDED.content,
|
|
13788
|
+
content_hash = EXCLUDED.content_hash`,
|
|
13789
|
+
[o.id, o.note_id, o.content, o.content_hash, o.created_at]
|
|
13790
|
+
);
|
|
13791
|
+
}
|
|
13792
|
+
for (const r of revised) {
|
|
13793
|
+
await db.query(
|
|
13794
|
+
`INSERT INTO note_revised_current (
|
|
13795
|
+
note_id, content, ai_metadata, generation_count, model, is_user_edited, updated_at
|
|
13796
|
+
)
|
|
13797
|
+
VALUES ($1, $2, $3::jsonb, $4, $5, $6, $7)
|
|
13798
|
+
ON CONFLICT (note_id) DO UPDATE SET
|
|
13799
|
+
content = EXCLUDED.content,
|
|
13800
|
+
ai_metadata = EXCLUDED.ai_metadata,
|
|
13801
|
+
generation_count = EXCLUDED.generation_count,
|
|
13802
|
+
model = EXCLUDED.model,
|
|
13803
|
+
is_user_edited = EXCLUDED.is_user_edited,
|
|
13804
|
+
updated_at = EXCLUDED.updated_at`,
|
|
13805
|
+
[
|
|
13806
|
+
r.id,
|
|
13807
|
+
r.content,
|
|
13808
|
+
r.ai_metadata == null ? null : JSON.stringify(r.ai_metadata),
|
|
13809
|
+
r.generation_count,
|
|
13810
|
+
r.model,
|
|
13811
|
+
r.is_user_edited,
|
|
13812
|
+
r.updated_at
|
|
13813
|
+
]
|
|
13814
|
+
);
|
|
13815
|
+
}
|
|
13816
|
+
for (const t of tags) {
|
|
13817
|
+
await db.query(
|
|
13818
|
+
`INSERT INTO note_tag (id, note_id, tag, created_at)
|
|
13819
|
+
VALUES ($1, $2, $3, $4)
|
|
13820
|
+
ON CONFLICT (note_id, tag) DO NOTHING`,
|
|
13821
|
+
[t.id, t.note_id, t.tag, t.created_at]
|
|
13822
|
+
);
|
|
13823
|
+
}
|
|
13824
|
+
await db.query(
|
|
13825
|
+
`DELETE FROM note_tag WHERE NOT (id = ANY($1::text[]))`,
|
|
13826
|
+
[tags.map((t) => t.id)]
|
|
13827
|
+
);
|
|
13828
|
+
for (const l of links) {
|
|
13829
|
+
await db.query(
|
|
13830
|
+
`INSERT INTO link (id, source_note_id, target_note_id, link_type, created_at, deleted_at)
|
|
13831
|
+
VALUES ($1, $2, $3, $4, $5, $6)
|
|
13832
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
13833
|
+
link_type = EXCLUDED.link_type,
|
|
13834
|
+
deleted_at = EXCLUDED.deleted_at`,
|
|
13835
|
+
[l.id, l.source_note_id, l.target_note_id, l.link_type, l.created_at, l.deleted_at]
|
|
13836
|
+
);
|
|
13837
|
+
}
|
|
13838
|
+
for (const m of memberships) {
|
|
13839
|
+
await db.query(
|
|
13840
|
+
`INSERT INTO collection_note (collection_id, note_id, position, added_at)
|
|
13841
|
+
VALUES ($1, $2, 0, $3)
|
|
13842
|
+
ON CONFLICT (collection_id, note_id) DO NOTHING`,
|
|
13843
|
+
[m.collection_id, m.note_id, m.created_at]
|
|
13844
|
+
);
|
|
13845
|
+
}
|
|
13846
|
+
await db.query(
|
|
13847
|
+
`DELETE FROM collection_note WHERE NOT ((collection_id || ':' || note_id) = ANY($1::text[]))`,
|
|
13848
|
+
[memberships.map((m) => `${m.collection_id}:${m.note_id}`)]
|
|
13849
|
+
);
|
|
13850
|
+
return {
|
|
13851
|
+
notes: noteRows.length,
|
|
13852
|
+
tags: tags.length,
|
|
13853
|
+
links: links.length,
|
|
13854
|
+
collections: collections.length,
|
|
13855
|
+
memberships: memberships.length
|
|
13856
|
+
};
|
|
13857
|
+
}
|
|
13858
|
+
async function projectRecords(db, store) {
|
|
13859
|
+
const notes = await projectNotes(db, store);
|
|
13860
|
+
const attachments = await projectAttachments(db, store);
|
|
13861
|
+
return { ...notes, attachments };
|
|
13862
|
+
}
|
|
13863
|
+
async function dropNoteProjection(db) {
|
|
13864
|
+
await db.query(`DELETE FROM collection_note`);
|
|
13865
|
+
await db.query(`DELETE FROM note_tag`);
|
|
13866
|
+
await db.query(`DELETE FROM link`);
|
|
13867
|
+
await db.query(`DELETE FROM note_revised_current`);
|
|
13868
|
+
await db.query(`DELETE FROM note_revision`);
|
|
13869
|
+
await db.query(`DELETE FROM note_original`);
|
|
13870
|
+
await db.query(`DELETE FROM job_queue`);
|
|
13871
|
+
await db.query(`DELETE FROM note`);
|
|
13872
|
+
await db.query(`DELETE FROM collection`);
|
|
13873
|
+
}
|
|
13874
|
+
|
|
13875
|
+
// src/records/record-backend.ts
|
|
13876
|
+
function noteToBackend(n, tags) {
|
|
13877
|
+
return {
|
|
13878
|
+
id: n.id,
|
|
13879
|
+
title: n.title,
|
|
13880
|
+
tags,
|
|
13881
|
+
createdAt: n.created_at,
|
|
13882
|
+
updatedAt: n.updated_at,
|
|
13883
|
+
source: n.source,
|
|
13884
|
+
starred: n.is_starred,
|
|
13885
|
+
archived: n.is_archived
|
|
13886
|
+
};
|
|
13887
|
+
}
|
|
13888
|
+
function linkToBackend2(link) {
|
|
13889
|
+
return {
|
|
13890
|
+
id: link.id,
|
|
13891
|
+
fromNoteId: link.source_note_id,
|
|
13892
|
+
toNoteId: link.target_note_id,
|
|
13893
|
+
kind: link.link_type,
|
|
13894
|
+
score: null,
|
|
13895
|
+
createdAt: link.created_at
|
|
13896
|
+
};
|
|
13897
|
+
}
|
|
13898
|
+
function createRecordBackend(store, options = {}) {
|
|
13899
|
+
const notes = new CanonicalNotesRepository(store);
|
|
13900
|
+
async function tagsByNote() {
|
|
13901
|
+
const map = /* @__PURE__ */ new Map();
|
|
13902
|
+
for (const row of await store.list("note_tag")) {
|
|
13903
|
+
const tags = map.get(row.note_id) ?? [];
|
|
13904
|
+
tags.push(row.tag);
|
|
13905
|
+
map.set(row.note_id, tags);
|
|
13906
|
+
}
|
|
13907
|
+
for (const tags of map.values()) tags.sort();
|
|
13908
|
+
return map;
|
|
13909
|
+
}
|
|
13910
|
+
return {
|
|
13911
|
+
id: options.id ?? "canonical-records",
|
|
13912
|
+
capabilities: {
|
|
13913
|
+
read: true,
|
|
13914
|
+
write: true,
|
|
13915
|
+
merge: true,
|
|
13916
|
+
// via importShardToRecords (record-shard.ts)
|
|
13917
|
+
multiUser: false,
|
|
13918
|
+
semantic: "none",
|
|
13919
|
+
startupCost: "instant"
|
|
13920
|
+
},
|
|
13921
|
+
async listNotes(o) {
|
|
13922
|
+
const all = (await store.list("note")).filter((n) => n.deleted_at === null);
|
|
13923
|
+
all.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
13924
|
+
const offset = o?.offset ?? 0;
|
|
13925
|
+
const limit = o?.limit ?? 50;
|
|
13926
|
+
const tags = await tagsByNote();
|
|
13927
|
+
return {
|
|
13928
|
+
items: all.slice(offset, offset + limit).map((n) => noteToBackend(n, tags.get(n.id) ?? [])),
|
|
13929
|
+
total: all.length
|
|
13930
|
+
};
|
|
13931
|
+
},
|
|
13932
|
+
async getNote(id) {
|
|
13933
|
+
const view = await notes.get(id);
|
|
13934
|
+
if (!view || view.note.deleted_at !== null) return null;
|
|
13935
|
+
return noteToBackend(view.note, view.tags);
|
|
13936
|
+
},
|
|
13937
|
+
async search(query, o) {
|
|
13938
|
+
const offset = o?.offset ?? 0;
|
|
13939
|
+
const limit = o?.limit ?? 20;
|
|
13940
|
+
let matched = await notes.searchText(query, offset + limit);
|
|
13941
|
+
if (o?.tags?.length) {
|
|
13942
|
+
const tags2 = await tagsByNote();
|
|
13943
|
+
matched = matched.filter((n) => o.tags.every((t) => (tags2.get(n.id) ?? []).includes(t)));
|
|
13944
|
+
}
|
|
13945
|
+
if (o?.source?.length) {
|
|
13946
|
+
matched = matched.filter((n) => o.source.includes(n.source));
|
|
13947
|
+
}
|
|
13948
|
+
const tags = await tagsByNote();
|
|
13949
|
+
const hits = matched.slice(offset, offset + limit).map((n) => ({ note: noteToBackend(n, tags.get(n.id) ?? []) }));
|
|
13950
|
+
return { hits, total: matched.length };
|
|
13951
|
+
},
|
|
13952
|
+
async getNoteFull(id) {
|
|
13953
|
+
const view = await notes.get(id);
|
|
13954
|
+
if (!view || view.note.deleted_at !== null) return null;
|
|
13955
|
+
return {
|
|
13956
|
+
...noteToBackend(view.note, view.tags),
|
|
13957
|
+
content: view.revised_content,
|
|
13958
|
+
links: (await notes.linksOf(id)).map(linkToBackend2)
|
|
13959
|
+
};
|
|
13960
|
+
},
|
|
13961
|
+
async linksOf(id) {
|
|
13962
|
+
return (await notes.linksOf(id)).map(linkToBackend2);
|
|
13963
|
+
},
|
|
13964
|
+
async manageNote(input) {
|
|
13965
|
+
const parsed = ManageNoteInputSchema.parse(input);
|
|
13966
|
+
switch (parsed.action) {
|
|
13967
|
+
case "update": {
|
|
13968
|
+
const note = await notes.update(parsed.note_id, {
|
|
13969
|
+
title: parsed.title,
|
|
13970
|
+
content: parsed.content,
|
|
13971
|
+
format: parsed.format,
|
|
13972
|
+
visibility: parsed.visibility
|
|
13973
|
+
});
|
|
13974
|
+
return { action: "update", note_id: parsed.note_id, note };
|
|
13975
|
+
}
|
|
13976
|
+
case "delete":
|
|
13977
|
+
await notes.softDelete(parsed.note_id);
|
|
13978
|
+
return { action: "delete", note_id: parsed.note_id };
|
|
13979
|
+
case "restore": {
|
|
13980
|
+
await notes.restore(parsed.note_id);
|
|
13981
|
+
return { action: "restore", note_id: parsed.note_id, note: await notes.get(parsed.note_id) };
|
|
13982
|
+
}
|
|
13983
|
+
case "archive": {
|
|
13984
|
+
const note = await notes.update(parsed.note_id, { is_archived: true });
|
|
13985
|
+
return { action: "archive", note_id: parsed.note_id, note };
|
|
13986
|
+
}
|
|
13987
|
+
case "unarchive": {
|
|
13988
|
+
const note = await notes.update(parsed.note_id, { is_archived: false });
|
|
13989
|
+
return { action: "unarchive", note_id: parsed.note_id, note };
|
|
13990
|
+
}
|
|
13991
|
+
case "star": {
|
|
13992
|
+
const note = await notes.update(parsed.note_id, { is_starred: true });
|
|
13993
|
+
return { action: "star", note_id: parsed.note_id, note };
|
|
13994
|
+
}
|
|
13995
|
+
case "unstar": {
|
|
13996
|
+
const note = await notes.update(parsed.note_id, { is_starred: false });
|
|
13997
|
+
return { action: "unstar", note_id: parsed.note_id, note };
|
|
13998
|
+
}
|
|
13999
|
+
}
|
|
14000
|
+
}
|
|
14001
|
+
};
|
|
14002
|
+
}
|
|
14003
|
+
|
|
14004
|
+
// src/records/record-shard.ts
|
|
14005
|
+
var encoder2 = new TextEncoder();
|
|
14006
|
+
var decoder6 = new TextDecoder();
|
|
14007
|
+
function emptyCounts() {
|
|
14008
|
+
return {
|
|
14009
|
+
notes: 0,
|
|
14010
|
+
collections: 0,
|
|
14011
|
+
templates: 0,
|
|
14012
|
+
tags: 0,
|
|
14013
|
+
links: 0,
|
|
14014
|
+
embedding_sets: 0,
|
|
14015
|
+
embedding_configs: 0,
|
|
14016
|
+
embedding_set_members: 0,
|
|
14017
|
+
embeddings: 0,
|
|
14018
|
+
skos_schemes: 0,
|
|
14019
|
+
skos_concepts: 0,
|
|
14020
|
+
skos_relations: 0,
|
|
14021
|
+
note_skos_tags: 0,
|
|
14022
|
+
provenance_edges: 0,
|
|
14023
|
+
graph_sources: 0,
|
|
14024
|
+
graph_edges: 0,
|
|
14025
|
+
community_sets: 0,
|
|
14026
|
+
communities: 0,
|
|
14027
|
+
community_assignments: 0
|
|
14028
|
+
};
|
|
14029
|
+
}
|
|
14030
|
+
async function exportShardFromRecords(store, options) {
|
|
14031
|
+
const files = /* @__PURE__ */ new Map();
|
|
14032
|
+
const components = [];
|
|
14033
|
+
const counts = {};
|
|
14034
|
+
const [allNotes, originals, revisedRows, tagRows, collections, memberships, attachments, blobs] = await Promise.all([
|
|
14035
|
+
store.list("note"),
|
|
14036
|
+
store.list("note_original"),
|
|
14037
|
+
store.list("note_revised_current"),
|
|
14038
|
+
store.list("note_tag"),
|
|
14039
|
+
store.list("collection"),
|
|
14040
|
+
store.list("collection_note"),
|
|
14041
|
+
store.list("attachment"),
|
|
14042
|
+
store.list("attachment_blob")
|
|
14043
|
+
]);
|
|
14044
|
+
const originalByNote = new Map(originals.map((o) => [o.note_id, o]));
|
|
14045
|
+
const revisedByNote = new Map(revisedRows.map((r) => [r.id, r]));
|
|
14046
|
+
const blobById = new Map(blobs.map((b) => [b.id, b]));
|
|
14047
|
+
const tagsByNote = /* @__PURE__ */ new Map();
|
|
14048
|
+
for (const row of [...tagRows].sort((a, b) => a.tag.localeCompare(b.tag))) {
|
|
14049
|
+
const tags = tagsByNote.get(row.note_id) ?? [];
|
|
14050
|
+
tags.push(row.tag);
|
|
14051
|
+
tagsByNote.set(row.note_id, tags);
|
|
14052
|
+
}
|
|
14053
|
+
const collectionByNote = /* @__PURE__ */ new Map();
|
|
14054
|
+
for (const m of [...memberships].sort((a, b) => a.created_at.localeCompare(b.created_at))) {
|
|
14055
|
+
if (!collectionByNote.has(m.note_id)) collectionByNote.set(m.note_id, m.collection_id);
|
|
14056
|
+
}
|
|
14057
|
+
const membershipNoteIds = /* @__PURE__ */ new Map();
|
|
14058
|
+
for (const m of memberships) {
|
|
14059
|
+
const set = membershipNoteIds.get(m.collection_id) ?? /* @__PURE__ */ new Set();
|
|
14060
|
+
set.add(m.note_id);
|
|
14061
|
+
membershipNoteIds.set(m.collection_id, set);
|
|
14062
|
+
}
|
|
14063
|
+
let notes = allNotes.filter((n) => n.deleted_at === null);
|
|
14064
|
+
if (options?.collectionId) {
|
|
14065
|
+
const inCollection = membershipNoteIds.get(options.collectionId) ?? /* @__PURE__ */ new Set();
|
|
14066
|
+
notes = notes.filter((n) => inCollection.has(n.id));
|
|
14067
|
+
} else if (options?.tag) {
|
|
14068
|
+
notes = notes.filter((n) => tagsByNote.get(n.id)?.includes(options.tag));
|
|
14069
|
+
}
|
|
14070
|
+
notes.sort((a, b) => a.created_at.localeCompare(b.created_at));
|
|
14071
|
+
const liveAttachments = attachments.filter((a) => a.deleted_at === null).sort((a, b) => a.position - b.position || a.created_at.localeCompare(b.created_at));
|
|
14072
|
+
const attachmentsByNote = /* @__PURE__ */ new Map();
|
|
14073
|
+
const exportedBlobChecksums = [];
|
|
14074
|
+
for (const att of liveAttachments) {
|
|
14075
|
+
const blob = blobById.get(att.blob_id);
|
|
14076
|
+
if (!blob) continue;
|
|
14077
|
+
const projection = {
|
|
14078
|
+
extracted_text: att.extracted_text,
|
|
14079
|
+
attachment: {
|
|
14080
|
+
// `path` is the display filename per the binary-attachment projection
|
|
14081
|
+
// contract — never a physical storage key.
|
|
14082
|
+
id: att.id,
|
|
14083
|
+
path: att.filename,
|
|
14084
|
+
mime: att.mime_type,
|
|
14085
|
+
checksum: blob.content_hash,
|
|
14086
|
+
bytes: blob.size_bytes
|
|
14087
|
+
}
|
|
14088
|
+
};
|
|
14089
|
+
const list = attachmentsByNote.get(att.note_id) ?? [];
|
|
14090
|
+
list.push(projection);
|
|
14091
|
+
attachmentsByNote.set(att.note_id, list);
|
|
14092
|
+
exportedBlobChecksums.push(blob.content_hash);
|
|
14093
|
+
}
|
|
14094
|
+
const browserNotes = notes.map((n) => {
|
|
14095
|
+
const revised = revisedByNote.get(n.id);
|
|
14096
|
+
return {
|
|
14097
|
+
id: n.id,
|
|
14098
|
+
title: n.title,
|
|
14099
|
+
format: n.format,
|
|
14100
|
+
source: n.source,
|
|
14101
|
+
is_starred: n.is_starred,
|
|
14102
|
+
is_archived: n.is_archived,
|
|
14103
|
+
created_at: n.created_at,
|
|
14104
|
+
updated_at: n.updated_at,
|
|
14105
|
+
deleted_at: n.deleted_at,
|
|
14106
|
+
original_content: originalByNote.get(n.id)?.content ?? "",
|
|
14107
|
+
revised_content: revised?.content ?? null,
|
|
14108
|
+
ai_metadata: revised?.ai_metadata ?? null,
|
|
14109
|
+
collection_id: collectionByNote.get(n.id) ?? null,
|
|
14110
|
+
attachments: attachmentsByNote.get(n.id),
|
|
14111
|
+
tags: tagsByNote.get(n.id) ?? []
|
|
14112
|
+
};
|
|
14113
|
+
});
|
|
14114
|
+
const exportedNoteIds = new Set(browserNotes.map((n) => n.id));
|
|
14115
|
+
const shardNotes = browserNotes.map((n) => noteToShard(n));
|
|
14116
|
+
let layout;
|
|
14117
|
+
const clusterSize = options?.clusterNotesSize;
|
|
14118
|
+
if (clusterSize && Number.isInteger(clusterSize) && clusterSize > 0 && shardNotes.length > 0) {
|
|
14119
|
+
const clusters = [];
|
|
14120
|
+
for (let offset = 0; offset < shardNotes.length; offset += clusterSize) {
|
|
14121
|
+
const slice = shardNotes.slice(offset, offset + clusterSize);
|
|
14122
|
+
const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
|
|
14123
|
+
clusters.push({ href, offset });
|
|
14124
|
+
files.set(href, encoder2.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
|
|
14125
|
+
}
|
|
14126
|
+
layout = { clusters: { notes: clusters } };
|
|
14127
|
+
} else {
|
|
14128
|
+
files.set("notes.jsonl", encoder2.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
|
|
14129
|
+
}
|
|
14130
|
+
components.push("notes");
|
|
14131
|
+
counts.notes = shardNotes.length;
|
|
14132
|
+
const liveCollections = collections.filter((c) => c.deleted_at === null).sort((a, b) => a.name.localeCompare(b.name));
|
|
14133
|
+
const shardCollections = liveCollections.map(
|
|
14134
|
+
(c) => collectionToShard(
|
|
14135
|
+
// Canonical collections are flat (no parent hierarchy yet).
|
|
14136
|
+
{ id: c.id, name: c.name, description: c.description, parent_id: null, created_at: c.created_at },
|
|
14137
|
+
membershipNoteIds.get(c.id)?.size ?? 0
|
|
14138
|
+
)
|
|
14139
|
+
);
|
|
14140
|
+
files.set("collections.json", encoder2.encode(JSON.stringify(shardCollections)));
|
|
14141
|
+
components.push("collections");
|
|
14142
|
+
counts.collections = shardCollections.length;
|
|
14143
|
+
const distinctTags = [...new Set(
|
|
14144
|
+
tagRows.filter((t) => exportedNoteIds.has(t.note_id) || !options?.collectionId && !options?.tag).map((t) => t.tag)
|
|
14145
|
+
)].sort();
|
|
14146
|
+
const shardTags = tagsToShard(distinctTags.map((name) => ({ name, created_at: /* @__PURE__ */ new Date() })));
|
|
14147
|
+
files.set("tags.json", encoder2.encode(JSON.stringify(shardTags)));
|
|
14148
|
+
components.push("tags");
|
|
14149
|
+
counts.tags = shardTags.length;
|
|
14150
|
+
const links = await store.list("link");
|
|
14151
|
+
const isFiltered = !!(options?.collectionId || options?.tag);
|
|
14152
|
+
const shardLinks = links.filter((l) => l.deleted_at === null).filter((l) => !isFiltered || exportedNoteIds.has(l.source_note_id) && exportedNoteIds.has(l.target_note_id)).sort((a, b) => a.created_at.localeCompare(b.created_at)).map((l) => linkToShard({
|
|
14153
|
+
id: l.id,
|
|
14154
|
+
source_note_id: l.source_note_id,
|
|
14155
|
+
target_note_id: l.target_note_id,
|
|
14156
|
+
link_type: l.link_type,
|
|
14157
|
+
// Canonical links carry no confidence score (PGlite-tier column).
|
|
14158
|
+
confidence: null,
|
|
14159
|
+
created_at: l.created_at
|
|
14160
|
+
}));
|
|
14161
|
+
files.set("links.jsonl", encoder2.encode(shardLinks.map((l) => JSON.stringify(l)).join("\n")));
|
|
14162
|
+
components.push("links");
|
|
14163
|
+
counts.links = shardLinks.length;
|
|
14164
|
+
const checksums = {};
|
|
14165
|
+
for (const [filename, data] of files) {
|
|
14166
|
+
checksums[filename] = await sha256Hex(data);
|
|
14167
|
+
}
|
|
14168
|
+
const manifest = {
|
|
14169
|
+
version: CURRENT_SHARD_VERSION,
|
|
14170
|
+
matric_version: VERSION,
|
|
14171
|
+
format: SHARD_FORMAT,
|
|
14172
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14173
|
+
components,
|
|
14174
|
+
counts,
|
|
14175
|
+
checksums,
|
|
14176
|
+
min_reader_version: "1.0.0",
|
|
14177
|
+
migrated_from: null,
|
|
14178
|
+
migration_history: [],
|
|
14179
|
+
...layout ? { layout } : {}
|
|
14180
|
+
};
|
|
14181
|
+
files.set("manifest.json", encoder2.encode(JSON.stringify(manifest, null, 2)));
|
|
14182
|
+
if (options?.includeBlobs && options.blobStore) {
|
|
14183
|
+
const packed = /* @__PURE__ */ new Set();
|
|
14184
|
+
for (const checksum of exportedBlobChecksums) {
|
|
14185
|
+
if (packed.has(checksum)) continue;
|
|
14186
|
+
packed.add(checksum);
|
|
14187
|
+
const bytes = await options.blobStore.read(checksum);
|
|
14188
|
+
if (bytes) files.set(sidecarEntryName(checksum), bytes);
|
|
14189
|
+
}
|
|
14190
|
+
}
|
|
14191
|
+
return packTarGz(files);
|
|
14192
|
+
}
|
|
14193
|
+
var UNSUPPORTED_COMPONENTS = [
|
|
14194
|
+
"templates",
|
|
14195
|
+
"embedding_sets",
|
|
14196
|
+
"embedding_configs",
|
|
14197
|
+
"embedding_set_members",
|
|
14198
|
+
"embeddings",
|
|
14199
|
+
"skos_schemes",
|
|
14200
|
+
"skos_concepts",
|
|
14201
|
+
"skos_relations",
|
|
14202
|
+
"note_skos_tags",
|
|
14203
|
+
"provenance_edges",
|
|
14204
|
+
"graph_sources",
|
|
14205
|
+
"graph_edges",
|
|
14206
|
+
"communities",
|
|
14207
|
+
"community_assignments"
|
|
14208
|
+
];
|
|
14209
|
+
function failure(counts, skipped, warnings, error, start) {
|
|
14210
|
+
return {
|
|
14211
|
+
success: false,
|
|
14212
|
+
counts,
|
|
14213
|
+
skipped,
|
|
14214
|
+
warnings,
|
|
14215
|
+
errors: [error],
|
|
14216
|
+
duration_ms: performance.now() - start
|
|
14217
|
+
};
|
|
14218
|
+
}
|
|
14219
|
+
async function importShardToRecords(store, data, options) {
|
|
14220
|
+
const start = performance.now();
|
|
14221
|
+
const strategy = options?.conflictStrategy ?? "skip";
|
|
14222
|
+
const counts = emptyCounts();
|
|
14223
|
+
const skipped = {};
|
|
14224
|
+
const warnings = [];
|
|
14225
|
+
const inputData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
14226
|
+
let files;
|
|
14227
|
+
try {
|
|
14228
|
+
files = unpackTarGz(inputData);
|
|
14229
|
+
} catch (err) {
|
|
14230
|
+
return failure(
|
|
14231
|
+
counts,
|
|
14232
|
+
skipped,
|
|
14233
|
+
warnings,
|
|
14234
|
+
`Failed to decompress archive: ${err instanceof Error ? err.message : String(err)}`,
|
|
14235
|
+
start
|
|
14236
|
+
);
|
|
14237
|
+
}
|
|
14238
|
+
const manifestData = files.get("manifest.json");
|
|
14239
|
+
if (!manifestData) {
|
|
14240
|
+
return failure(counts, skipped, warnings, "Missing manifest.json in shard archive", start);
|
|
14241
|
+
}
|
|
14242
|
+
let manifest;
|
|
14243
|
+
try {
|
|
14244
|
+
manifest = JSON.parse(decoder6.decode(manifestData));
|
|
14245
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
14246
|
+
throw new Error("manifest must be a JSON object");
|
|
14247
|
+
}
|
|
14248
|
+
} catch {
|
|
14249
|
+
return failure(counts, skipped, warnings, "Invalid manifest.json: failed to parse JSON", start);
|
|
14250
|
+
}
|
|
14251
|
+
if (manifest.min_reader_version && compareShardVersions(manifest.min_reader_version, CURRENT_SHARD_VERSION) > 0) {
|
|
14252
|
+
return failure(
|
|
14253
|
+
counts,
|
|
14254
|
+
skipped,
|
|
14255
|
+
warnings,
|
|
14256
|
+
`Shard requires reader version ${manifest.min_reader_version}, but this version supports up to ${CURRENT_SHARD_VERSION}`,
|
|
14257
|
+
start
|
|
14258
|
+
);
|
|
14259
|
+
}
|
|
14260
|
+
const sigError = await enforceSignaturePolicy(files, options, warnings);
|
|
14261
|
+
if (sigError) return failure(counts, skipped, warnings, sigError, start);
|
|
14262
|
+
if (!manifest.checksums || typeof manifest.checksums !== "object") {
|
|
14263
|
+
return failure(counts, skipped, warnings, "Invalid manifest.json: checksums must be an object", start);
|
|
14264
|
+
}
|
|
14265
|
+
const checksumResult = await validateChecksums(manifest.checksums, files);
|
|
14266
|
+
if (!checksumResult.valid) {
|
|
14267
|
+
return failure(
|
|
14268
|
+
counts,
|
|
14269
|
+
skipped,
|
|
14270
|
+
warnings,
|
|
14271
|
+
`Checksum validation failed for: ${checksumResult.failures.join(", ")}`,
|
|
14272
|
+
start
|
|
14273
|
+
);
|
|
14274
|
+
}
|
|
14275
|
+
const sidecarBlobs = options?.blobStore ? collectSidecarBlobs(files) : null;
|
|
14276
|
+
const noteClusters = manifest.layout?.clusters?.notes;
|
|
14277
|
+
let parsedNotes;
|
|
14278
|
+
let parsedCollections;
|
|
14279
|
+
let parsedLinks;
|
|
14280
|
+
try {
|
|
14281
|
+
parsedNotes = noteClusters && noteClusters.length > 0 ? [...noteClusters].sort((a, b) => a.offset - b.offset).flatMap((ref) => parseJsonlBytes(files.get(ref.href))) : parseJsonlBytes(files.get("notes.jsonl"));
|
|
14282
|
+
parsedCollections = parseJsonArrayBytes(files.get("collections.json"));
|
|
14283
|
+
parsedLinks = parseJsonlBytes(files.get("links.jsonl"));
|
|
14284
|
+
} catch (err) {
|
|
14285
|
+
return failure(
|
|
14286
|
+
counts,
|
|
14287
|
+
skipped,
|
|
14288
|
+
warnings,
|
|
14289
|
+
`Failed to parse shard component: ${err instanceof Error ? err.message : String(err)}`,
|
|
14290
|
+
start
|
|
14291
|
+
);
|
|
14292
|
+
}
|
|
14293
|
+
for (const component of manifest.components ?? []) {
|
|
14294
|
+
if (UNSUPPORTED_COMPONENTS.includes(component)) {
|
|
14295
|
+
const count = manifest.counts?.[component];
|
|
14296
|
+
const key = component === "communities" ? "communities" : component;
|
|
14297
|
+
skipped[key] = (skipped[key] ?? 0) + (typeof count === "number" ? count : 0);
|
|
14298
|
+
warnings.push(
|
|
14299
|
+
`Shard component '${component}' is not supported by the canonical record tier and was skipped. Import into a PGlite-backed store to preserve it.`
|
|
14300
|
+
);
|
|
14301
|
+
}
|
|
14302
|
+
}
|
|
14303
|
+
if (strategy === "error") {
|
|
14304
|
+
for (const col of parsedCollections) {
|
|
14305
|
+
if (await store.get("collection", col.id)) {
|
|
14306
|
+
return failure(counts, skipped, warnings, `Collection already exists: ${col.id}`, start);
|
|
14307
|
+
}
|
|
14308
|
+
}
|
|
14309
|
+
for (const shardNote of parsedNotes) {
|
|
14310
|
+
if (await store.get("note", shardNote.id)) {
|
|
14311
|
+
return failure(counts, skipped, warnings, `Note already exists: ${shardNote.id}`, start);
|
|
14312
|
+
}
|
|
14313
|
+
}
|
|
14314
|
+
}
|
|
14315
|
+
const nowIso3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
14316
|
+
for (const shardCol of parsedCollections) {
|
|
14317
|
+
const col = collectionFromShard(shardCol);
|
|
14318
|
+
const existing = await store.get("collection", col.id);
|
|
14319
|
+
if (existing && strategy === "skip") {
|
|
14320
|
+
skipped.collections = (skipped.collections ?? 0) + 1;
|
|
14321
|
+
continue;
|
|
14322
|
+
}
|
|
14323
|
+
await store.put("collection", {
|
|
14324
|
+
id: col.id,
|
|
14325
|
+
name: col.name,
|
|
14326
|
+
description: col.description,
|
|
14327
|
+
created_at: col.created_at,
|
|
14328
|
+
updated_at: existing?.updated_at ?? nowIso3,
|
|
14329
|
+
deleted_at: existing?.deleted_at ?? null
|
|
14330
|
+
});
|
|
14331
|
+
counts.collections++;
|
|
14332
|
+
}
|
|
14333
|
+
const existingBlobs = await store.list("attachment_blob");
|
|
14334
|
+
const blobIdByChecksum = new Map(existingBlobs.map((b) => [b.content_hash, b.id]));
|
|
14335
|
+
const blobsToHydrate = /* @__PURE__ */ new Map();
|
|
14336
|
+
let referenceOnlyCount = 0;
|
|
14337
|
+
let notesWithAttachmentRefs = 0;
|
|
14338
|
+
for (const shardNote of parsedNotes) {
|
|
14339
|
+
const note = noteFromShard(shardNote);
|
|
14340
|
+
const existing = await store.get("note", note.id);
|
|
14341
|
+
if (existing && strategy === "skip") {
|
|
14342
|
+
skipped.notes = (skipped.notes ?? 0) + 1;
|
|
14343
|
+
continue;
|
|
14344
|
+
}
|
|
14345
|
+
await store.put("note", {
|
|
14346
|
+
id: note.id,
|
|
14347
|
+
archive_id: existing?.archive_id ?? null,
|
|
14348
|
+
title: note.title,
|
|
14349
|
+
format: note.format,
|
|
14350
|
+
source: note.source,
|
|
14351
|
+
visibility: existing?.visibility ?? "private",
|
|
14352
|
+
revision_mode: existing?.revision_mode ?? "standard",
|
|
14353
|
+
is_starred: note.is_starred,
|
|
14354
|
+
is_pinned: existing?.is_pinned ?? false,
|
|
14355
|
+
is_archived: note.is_archived,
|
|
14356
|
+
created_at: typeof note.created_at === "string" ? note.created_at : note.created_at.toISOString(),
|
|
14357
|
+
updated_at: typeof note.updated_at === "string" ? note.updated_at : note.updated_at.toISOString(),
|
|
14358
|
+
deleted_at: note.deleted_at ? typeof note.deleted_at === "string" ? note.deleted_at : note.deleted_at.toISOString() : null
|
|
14359
|
+
});
|
|
14360
|
+
const contentHash = computeHash(encoder2.encode(note.original_content));
|
|
14361
|
+
const existingOriginal = existing ? (await store.list("note_original")).find((o) => o.note_id === note.id) : void 0;
|
|
14362
|
+
await store.put("note_original", {
|
|
14363
|
+
id: existingOriginal?.id ?? generateId(),
|
|
14364
|
+
note_id: note.id,
|
|
14365
|
+
content: note.original_content,
|
|
14366
|
+
content_hash: contentHash,
|
|
14367
|
+
created_at: existingOriginal?.created_at ?? nowIso3
|
|
14368
|
+
});
|
|
14369
|
+
const existingRevised = existing ? await store.get("note_revised_current", note.id) : null;
|
|
14370
|
+
await store.put("note_revised_current", {
|
|
14371
|
+
id: note.id,
|
|
14372
|
+
content: note.revised_content ?? note.original_content,
|
|
14373
|
+
ai_metadata: note.ai_metadata ?? null,
|
|
14374
|
+
generation_count: existingRevised?.generation_count ?? 0,
|
|
14375
|
+
model: existingRevised?.model ?? null,
|
|
14376
|
+
is_user_edited: existingRevised?.is_user_edited ?? false,
|
|
14377
|
+
updated_at: typeof note.updated_at === "string" ? note.updated_at : note.updated_at.toISOString()
|
|
14378
|
+
});
|
|
14379
|
+
const existingTags = new Set(
|
|
14380
|
+
(await store.list("note_tag")).filter((t) => t.note_id === note.id).map((t) => t.tag)
|
|
14381
|
+
);
|
|
14382
|
+
for (const tag of note.tags) {
|
|
14383
|
+
if (existingTags.has(tag)) continue;
|
|
14384
|
+
await store.put("note_tag", { id: generateId(), note_id: note.id, tag, created_at: nowIso3 });
|
|
14385
|
+
}
|
|
14386
|
+
if (note.collection_id && await store.get("collection", note.collection_id)) {
|
|
14387
|
+
const member = (await store.list("collection_note")).find(
|
|
14388
|
+
(cn) => cn.collection_id === note.collection_id && cn.note_id === note.id
|
|
14389
|
+
);
|
|
14390
|
+
if (!member) {
|
|
14391
|
+
await store.put("collection_note", {
|
|
14392
|
+
id: generateId(),
|
|
14393
|
+
collection_id: note.collection_id,
|
|
14394
|
+
note_id: note.id,
|
|
14395
|
+
created_at: nowIso3
|
|
14396
|
+
});
|
|
14397
|
+
}
|
|
14398
|
+
}
|
|
14399
|
+
if (note.attachments?.length) {
|
|
14400
|
+
notesWithAttachmentRefs++;
|
|
14401
|
+
for (let position = 0; position < note.attachments.length; position += 1) {
|
|
14402
|
+
const projection = note.attachments[position];
|
|
14403
|
+
const ref = projection.attachment;
|
|
14404
|
+
let blobId = blobIdByChecksum.get(ref.checksum);
|
|
14405
|
+
if (!blobId) {
|
|
14406
|
+
const blob = {
|
|
14407
|
+
id: generateId(),
|
|
14408
|
+
content_hash: ref.checksum,
|
|
14409
|
+
size_bytes: ref.bytes,
|
|
14410
|
+
created_at: nowIso3
|
|
14411
|
+
};
|
|
14412
|
+
await store.put("attachment_blob", blob);
|
|
14413
|
+
blobIdByChecksum.set(ref.checksum, blob.id);
|
|
14414
|
+
blobId = blob.id;
|
|
14415
|
+
}
|
|
14416
|
+
const filename = ref.path.split("/").filter(Boolean).pop() ?? ref.path;
|
|
14417
|
+
const attachment = {
|
|
14418
|
+
id: ref.id,
|
|
14419
|
+
note_id: note.id,
|
|
14420
|
+
blob_id: blobId,
|
|
14421
|
+
document_type_id: null,
|
|
14422
|
+
mime_type: ref.mime,
|
|
14423
|
+
extracted_text: projection.extracted_text,
|
|
14424
|
+
filename,
|
|
14425
|
+
display_name: null,
|
|
14426
|
+
position,
|
|
14427
|
+
created_at: nowIso3,
|
|
14428
|
+
deleted_at: null
|
|
14429
|
+
};
|
|
14430
|
+
const existingAttachment = await store.get("attachment", ref.id);
|
|
14431
|
+
if (!existingAttachment || strategy === "replace") {
|
|
14432
|
+
await store.put("attachment", {
|
|
14433
|
+
...attachment,
|
|
14434
|
+
created_at: existingAttachment?.created_at ?? nowIso3
|
|
14435
|
+
});
|
|
14436
|
+
}
|
|
14437
|
+
let hydrated = false;
|
|
14438
|
+
if (sidecarBlobs) {
|
|
14439
|
+
if (blobsToHydrate.has(ref.checksum)) {
|
|
14440
|
+
hydrated = true;
|
|
14441
|
+
} else {
|
|
14442
|
+
const bytes = sidecarBlobs.get(blobChecksumToHex(ref.checksum));
|
|
14443
|
+
if (bytes) {
|
|
14444
|
+
if (computeBlobHash(bytes) === ref.checksum) {
|
|
14445
|
+
blobsToHydrate.set(ref.checksum, bytes);
|
|
14446
|
+
hydrated = true;
|
|
14447
|
+
} else {
|
|
14448
|
+
warnings.push(
|
|
14449
|
+
`Sidecar blob for attachment ${ref.id} failed BLAKE3 integrity check (expected ${ref.checksum}); imported as reference-only.`
|
|
14450
|
+
);
|
|
14451
|
+
}
|
|
14452
|
+
}
|
|
14453
|
+
}
|
|
14454
|
+
}
|
|
14455
|
+
if (!hydrated) referenceOnlyCount++;
|
|
14456
|
+
}
|
|
14457
|
+
}
|
|
14458
|
+
counts.notes++;
|
|
14459
|
+
}
|
|
14460
|
+
if (referenceOnlyCount > 0) {
|
|
14461
|
+
warnings.push(
|
|
14462
|
+
`${referenceOnlyCount} attachment reference(s) across ${notesWithAttachmentRefs} note(s) were imported as metadata only: no matching byte-sidecar entry (or no import blobStore), so getBlob() returns null until bytes are hydrated. Export a self-contained shard (\`includeBlobs\` + a \`blobStore\`) and import with a \`blobStore\` to hydrate bytes.`
|
|
14463
|
+
);
|
|
14464
|
+
}
|
|
14465
|
+
for (const shardLink of parsedLinks) {
|
|
14466
|
+
const link = linkFromShard(shardLink);
|
|
14467
|
+
if (!link.target_note_id) {
|
|
14468
|
+
skipped.links = (skipped.links ?? 0) + 1;
|
|
14469
|
+
warnings.push(
|
|
14470
|
+
link.to_url ? `URL link ${link.id} skipped: the canonical record tier does not persist URL-target links.` : `Shard link skipped: ${link.id} has neither to_note_id nor to_url.`
|
|
14471
|
+
);
|
|
14472
|
+
continue;
|
|
14473
|
+
}
|
|
14474
|
+
const existing = await store.get("link", link.id);
|
|
14475
|
+
if (existing && strategy === "skip") {
|
|
14476
|
+
skipped.links = (skipped.links ?? 0) + 1;
|
|
14477
|
+
continue;
|
|
14478
|
+
}
|
|
14479
|
+
await store.put("link", {
|
|
14480
|
+
id: link.id,
|
|
14481
|
+
source_note_id: link.source_note_id,
|
|
14482
|
+
target_note_id: link.target_note_id,
|
|
14483
|
+
link_type: link.link_type,
|
|
14484
|
+
created_at: link.created_at,
|
|
14485
|
+
deleted_at: existing?.deleted_at ?? null
|
|
14486
|
+
});
|
|
14487
|
+
counts.links++;
|
|
14488
|
+
}
|
|
14489
|
+
const errors = [];
|
|
14490
|
+
if (options?.blobStore && blobsToHydrate.size > 0) {
|
|
14491
|
+
try {
|
|
14492
|
+
for (const [, bytes] of blobsToHydrate) {
|
|
14493
|
+
await options.blobStore.put(bytes);
|
|
14494
|
+
}
|
|
14495
|
+
} catch (err) {
|
|
14496
|
+
warnings.push(
|
|
14497
|
+
`Imported records successfully but failed to hydrate ${blobsToHydrate.size} attachment blob(s) into the BlobStore: ${err instanceof Error ? err.message : String(err)}.`
|
|
14498
|
+
);
|
|
14499
|
+
}
|
|
14500
|
+
}
|
|
14501
|
+
return {
|
|
14502
|
+
success: true,
|
|
14503
|
+
counts,
|
|
14504
|
+
skipped,
|
|
14505
|
+
warnings,
|
|
14506
|
+
errors,
|
|
14507
|
+
duration_ms: performance.now() - start
|
|
14508
|
+
};
|
|
14509
|
+
}
|
|
14510
|
+
|
|
13721
14511
|
// src/index.ts
|
|
13722
|
-
var VERSION = "2026.7.
|
|
14512
|
+
var VERSION = "2026.7.8";
|
|
13723
14513
|
|
|
13724
|
-
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DB_SNAPSHOT_SCHEMA_VERSION, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LOCAL_ENDPOINTS, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, computeBlobHash, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createPGliteBackend, createPGliteInstance, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createWorkerEmbedFunction, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, dropAttachmentProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getEmbedFunction, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, handleEmbedRequests, hasFortemiSecureSecrets, importShard, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, migrateLegacyBlobStore, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, projectAttachments, provenanceEdgeToShard, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateFortemiCompatibilityResponse, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
14514
|
+
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DB_SNAPSHOT_SCHEMA_VERSION, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LOCAL_ENDPOINTS, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, TagsRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, computeBlobHash, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createWorkerEmbedFunction, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, exportShardFromRecords, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getEmbedFunction, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, handleEmbedRequests, hasFortemiSecureSecrets, importShard, importShardToRecords, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, migrateLegacyBlobStore, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateFortemiCompatibilityResponse, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
13725
14515
|
//# sourceMappingURL=index.js.map
|
|
13726
14516
|
//# sourceMappingURL=index.js.map
|