@bitcobblers/wod-wiki-engine 0.44.2160 → 0.45.2167

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.cjs CHANGED
@@ -617,13 +617,13 @@ function csvToSessionRows(csv) {
617
617
  }
618
618
 
619
619
  // src/version.ts
620
- var VERSION = "0.44.2160";
621
- var GIT_SHA = "d191f5e";
622
- var BUILD_TIME = "2026-10-24T23:21:37.364Z";
620
+ var VERSION = "0.45.2167";
621
+ var GIT_SHA = "d9859fd";
622
+ var BUILD_TIME = "2026-10-26T20:26:47.975Z";
623
623
  var SEMVER = {
624
- version: "0.44.2160",
625
- gitSha: "d191f5e",
626
- buildTime: "2026-10-24T23:21:37.364Z"
624
+ version: "0.45.2167",
625
+ gitSha: "d9859fd",
626
+ buildTime: "2026-10-26T20:26:47.975Z"
627
627
  };
628
628
  var SEED_SCHEMA = 9;
629
629
  var SEED_REGISTERED_WIDGETS = wodWikiCore.KNOWN_SECTION_WIDGETS;
@@ -651,15 +651,17 @@ var EFFORTS_CHUNK_ID = "efforts";
651
651
  var EQUIPMENT_CHUNK_ID = "equipment";
652
652
  var CANVAS_CHUNK_ID = "canvas";
653
653
  var DASHBOARDS_CHUNK_ID = "dashboards";
654
- var TEMPLATE_CHUNK_ID = "template";
655
654
  function seedMetaKey(sourceId) {
656
655
  return `seed:${sourceId}`;
657
656
  }
657
+ function feedIdOfMetaKey(metaKey) {
658
+ return metaKey.startsWith("seed:") ? metaKey.slice(5) : metaKey;
659
+ }
658
660
  function emptySeedMeta(key) {
659
661
  return { key, schema: SEED_SCHEMA, seedVersion: 0, builtAt: "", importedAt: 0, chunks: {}, claim: null };
660
662
  }
661
- function catalogForChunkId(chunkId) {
662
- const value = /^(?:collection|feed)\.(.+)$/.exec(chunkId)?.[1];
663
+ function notebookSlugForChunkId(chunkId) {
664
+ const value = /^notebook\.(.+)$/.exec(chunkId)?.[1];
663
665
  return value && value !== "_root" ? value : void 0;
664
666
  }
665
667
  function canvasRouteSlug(content) {
@@ -675,12 +677,10 @@ function seedNoteSourceId(path, content, chunkId) {
675
677
  if (chunkId === DASHBOARDS_CHUNK_ID) return "dashboards";
676
678
  if (chunkId === EFFORTS_CHUNK_ID) return "efforts";
677
679
  if (chunkId === EQUIPMENT_CHUNK_ID) return "equipment";
678
- if (chunkId === TEMPLATE_CHUNK_ID) return "playground";
679
- if (chunkId.startsWith("collection.")) {
680
- const catalog = catalogForChunkId(chunkId);
681
- return !catalog ? "collection:_root" : stem.toLowerCase() === "readme" ? `collection:${catalog}` : `collection:${catalog}/${stem}`;
680
+ if (chunkId.startsWith("notebook.")) {
681
+ const slug = notebookSlugForChunkId(chunkId);
682
+ return !slug ? "notebook:_root" : stem.toLowerCase() === "readme" ? `notebook:${slug}` : `notebook:${under}`;
682
683
  }
683
- if (chunkId.startsWith("feed.")) return `feed:feeds/${under}`;
684
684
  return void 0;
685
685
  }
686
686
  function object(value) {
@@ -807,11 +807,12 @@ async function applyDefinitionChunk(defStore, noteStore, parse, family, seedSour
807
807
  return max;
808
808
  };
809
809
  const projections = [];
810
+ const feedSourceId = seedSource;
810
811
  for (const [i, row] of rows.entries()) {
811
812
  if (!owned.has(ids[i])) continue;
812
813
  const parsed = parse(row.content);
813
814
  if (!parsed) continue;
814
- projections.push({ ...parsed, registrySource: "bundled", ownerNoteId: ids[i], sourceId: seedSource, sourcePath: row.path });
815
+ projections.push({ ...parsed, registrySource: "bundled", ownerNoteId: ids[i], sourceId: feedSourceId, sourcePath: row.path });
815
816
  }
816
817
  const prior = await defStore.getMany(projections.map((p) => p.slug));
817
818
  const changed = projections.filter((p, i) => {
@@ -916,6 +917,7 @@ async function applySeedChunk(storage, write) {
916
917
  const stored = await noteStore.getMany(allIds);
917
918
  const existingById = new Map(allIds.map((id, i) => [id, stored[i]]));
918
919
  const seedSource = write.meta.key.startsWith("seed:") ? write.meta.key.slice(5) : write.meta.key;
920
+ const feedSourceId = feedIdOfMetaKey(write.meta.key);
919
921
  const incomingRank = seedPrecedenceRank(write.meta.key, write.meta.tier);
920
922
  const otherCheckpoints = [];
921
923
  for (const row of await metaStore.getAll()) {
@@ -1004,7 +1006,7 @@ async function applySeedChunk(storage, write) {
1004
1006
  date = ts;
1005
1007
  }
1006
1008
  const seedCommit = row.commit ?? write.manifest.commit;
1007
- const note = { ...existing, id, title, rawContent: row.content, sourceRevision, blocks: map, createdAt: write.manifest.version, ...date === void 0 ? {} : { date }, type: write.chunkId === DASHBOARDS_CHUNK_ID ? "dashboard" : "note", sourceId, catalog: catalogForChunkId(write.chunkId ?? ""), seedOrigin: "seed", seedVersion: write.manifest.version, seedChunkId: write.chunkId ?? void 0, sourcePath: row.path, ...seedCommit ? { seedCommit } : {} };
1009
+ const note = { ...existing, id, title, rawContent: row.content, sourceRevision, blocks: map, createdAt: write.manifest.version, ...date === void 0 ? {} : { date }, type: write.chunkId === DASHBOARDS_CHUNK_ID ? "dashboard" : "note", sourceId, seedOrigin: "seed", seedVersion: write.manifest.version, seedChunkId: write.chunkId ?? void 0, feedOrigin: "feed", feedSourceId, sourcePath: row.path, ...seedCommit ? { seedCommit } : {} };
1008
1010
  if (date === void 0) delete note.date;
1009
1011
  if (!equal(note, existing)) changedNotes.push(note);
1010
1012
  const byRange = new Map(Object.values(map).map((b) => [`${b.from}:${b.to}`, b]));
@@ -1091,6 +1093,90 @@ async function applySeedChunk(storage, write) {
1091
1093
  return result;
1092
1094
  });
1093
1095
  }
1096
+ function owningFeed(claims, note) {
1097
+ const byChunk = note.seedChunkId ? claims.filter((claim) => claim.chunkId === note.seedChunkId) : [];
1098
+ const pool = byChunk.length > 0 ? byChunk : claims;
1099
+ return [...pool].sort((a, b) => b.rank - a.rank || (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))[0];
1100
+ }
1101
+ async function backfillFeedProvenance(storage) {
1102
+ return await storage.transaction(["meta", "notes", "block_index"], "readwrite", async (tx) => {
1103
+ const metaStore = tx.readwrite("meta");
1104
+ const claims = /* @__PURE__ */ new Map();
1105
+ for (const row of await metaStore.getAll()) {
1106
+ const meta = row;
1107
+ if (!meta || typeof meta.key !== "string" || !meta.key.startsWith("seed:")) continue;
1108
+ const sourceId = meta.key.slice("seed:".length);
1109
+ const rank = seedPrecedenceRank(meta.key, meta.tier);
1110
+ for (const [chunkId, chunk] of Object.entries(meta.chunks ?? {})) {
1111
+ for (const noteId of chunk.noteIds ?? []) {
1112
+ const list = claims.get(noteId) ?? [];
1113
+ list.push({ sourceId, chunkId, rank, key: meta.key });
1114
+ claims.set(noteId, list);
1115
+ }
1116
+ }
1117
+ }
1118
+ if (claims.size === 0) return 0;
1119
+ const noteStore = tx.readwrite("notes");
1120
+ const indexStore = tx.readwrite("block_index");
1121
+ const ids = [...claims.keys()];
1122
+ const stored = await noteStore.getMany(ids);
1123
+ const repaired = [];
1124
+ for (let i = 0; i < ids.length; i++) {
1125
+ const id = ids[i];
1126
+ const note = stored[i];
1127
+ if (!note || note.seedOrigin !== "seed" || note.feedSourceId) continue;
1128
+ const owner = owningFeed(claims.get(id), note);
1129
+ const sourceRevision = note.sourceRevision + 1;
1130
+ const blocks = Object.fromEntries(
1131
+ Object.entries(note.blocks).map(([blockId, block]) => [blockId, { ...block, sourceRevision }])
1132
+ );
1133
+ await noteStore.put({ ...note, blocks, sourceRevision, feedOrigin: "feed", feedSourceId: owner.sourceId });
1134
+ repaired.push({ id, sourceRevision });
1135
+ }
1136
+ if (repaired.length > 0) {
1137
+ const revisions = new Map(repaired.map((entry) => [entry.id, entry.sourceRevision]));
1138
+ const projections = await indexStore.getAllFromIndexMany("by-note", repaired.map((entry) => entry.id));
1139
+ const changed = projections.flatMap((rows) => rows.flatMap((row) => {
1140
+ const revision = revisions.get(row.noteId);
1141
+ return revision !== void 0 && row.sourceRevision !== revision ? [{ ...row, sourceRevision: revision }] : [];
1142
+ }));
1143
+ if (changed.length > 0) await indexStore.putMany(changed);
1144
+ }
1145
+ return repaired.length;
1146
+ });
1147
+ }
1148
+ async function migrateNotebookVocabulary(storage) {
1149
+ return await storage.transaction(["meta", "notes", "block_index", "block_efforts", "block_equipment"], "readwrite", async (tx) => {
1150
+ let migrated = 0;
1151
+ const metaStore = tx.readwrite("meta");
1152
+ for (const row of await metaStore.getAll()) {
1153
+ const meta = row;
1154
+ if (!meta || typeof meta.key !== "string" || !meta.key.startsWith("seed:")) continue;
1155
+ const chunks = meta.chunks ?? {};
1156
+ let renamed = false;
1157
+ const next = {};
1158
+ for (const [chunkId, chunk] of Object.entries(chunks)) {
1159
+ const id = wodWikiWql.migrateLegacyChunkId(chunkId);
1160
+ if (id !== chunkId) renamed = true;
1161
+ next[id] = next[id] && next[id] !== chunk ? { ...next[id], noteIds: [.../* @__PURE__ */ new Set([...next[id].noteIds ?? [], ...chunk.noteIds ?? []])] } : chunk;
1162
+ }
1163
+ if (renamed) {
1164
+ await metaStore.put({ ...meta, chunks: next });
1165
+ migrated++;
1166
+ }
1167
+ }
1168
+ for (const storeName of ["notes", "block_index", "block_efforts", "block_equipment"]) {
1169
+ const store = tx.readwrite(storeName);
1170
+ for (const row of await store.getAll()) {
1171
+ const record = row;
1172
+ if (!wodWikiWql.hasLegacyIdentity(record)) continue;
1173
+ await store.put(wodWikiWql.migrateLegacyRow(record));
1174
+ migrated++;
1175
+ }
1176
+ }
1177
+ return migrated;
1178
+ });
1179
+ }
1094
1180
 
1095
1181
  Object.defineProperty(exports, "ABSENT", {
1096
1182
  enumerable: true,
@@ -1128,13 +1214,13 @@ Object.defineProperty(exports, "BlockBuilder", {
1128
1214
  enumerable: true,
1129
1215
  get: function () { return wodWikiLang.BlockBuilder; }
1130
1216
  });
1131
- Object.defineProperty(exports, "ButtonBehavior", {
1217
+ Object.defineProperty(exports, "BlockContext", {
1132
1218
  enumerable: true,
1133
- get: function () { return wodWikiLang.ButtonBehavior; }
1219
+ get: function () { return wodWikiLang.BlockContext; }
1134
1220
  });
1135
- Object.defineProperty(exports, "CATALOG_PRECEDENCE_RANK", {
1221
+ Object.defineProperty(exports, "ButtonBehavior", {
1136
1222
  enumerable: true,
1137
- get: function () { return wodWikiLang.CATALOG_PRECEDENCE_RANK; }
1223
+ get: function () { return wodWikiLang.ButtonBehavior; }
1138
1224
  });
1139
1225
  Object.defineProperty(exports, "CONSUMED_HINTS", {
1140
1226
  enumerable: true,
@@ -1392,6 +1478,10 @@ Object.defineProperty(exports, "RuntimeStack", {
1392
1478
  enumerable: true,
1393
1479
  get: function () { return wodWikiLang.RuntimeStack; }
1394
1480
  });
1481
+ Object.defineProperty(exports, "SEED_PRECEDENCE_RANK", {
1482
+ enumerable: true,
1483
+ get: function () { return wodWikiLang.SEED_PRECEDENCE_RANK; }
1484
+ });
1395
1485
  Object.defineProperty(exports, "SOUND_PLAY_EVENT", {
1396
1486
  enumerable: true,
1397
1487
  get: function () { return wodWikiLang.SOUND_PLAY_EVENT; }
@@ -1888,6 +1978,10 @@ Object.defineProperty(exports, "WQL_TAG_KEYS", {
1888
1978
  enumerable: true,
1889
1979
  get: function () { return wodWikiWql.WQL_TAG_KEYS; }
1890
1980
  });
1981
+ Object.defineProperty(exports, "WQL_TYPED_TAG_KEYS", {
1982
+ enumerable: true,
1983
+ get: function () { return wodWikiWql.WQL_TYPED_TAG_KEYS; }
1984
+ });
1891
1985
  Object.defineProperty(exports, "WQL_VIRTUAL_DIMS", {
1892
1986
  enumerable: true,
1893
1987
  get: function () { return wodWikiWql.WQL_VIRTUAL_DIMS; }
@@ -2013,20 +2107,18 @@ exports.GIT_SHA = GIT_SHA;
2013
2107
  exports.NOTE_ID_FRONTMATTER_KEY = NOTE_ID_FRONTMATTER_KEY;
2014
2108
  exports.SEED_BROADCAST_CHANNEL = SEED_BROADCAST_CHANNEL;
2015
2109
  exports.SEED_NAMESPACE = SEED_NAMESPACE;
2016
- exports.SEED_PRECEDENCE_RANK = SEED_PRECEDENCE_RANK;
2017
2110
  exports.SEED_REGISTERED_WIDGETS = SEED_REGISTERED_WIDGETS;
2018
2111
  exports.SEED_SCHEMA = SEED_SCHEMA;
2019
2112
  exports.SEMVER = SEMVER;
2020
2113
  exports.SESSION_CSV_HEADER = SESSION_CSV_HEADER;
2021
- exports.TEMPLATE_CHUNK_ID = TEMPLATE_CHUNK_ID;
2022
2114
  exports.VERSION = VERSION;
2023
2115
  exports.applySeedChunk = applySeedChunk;
2024
2116
  exports.assertSeedManifest = assertSeedManifest;
2025
2117
  exports.assertSeedRow = assertSeedRow;
2026
2118
  exports.assertSeedRows = assertSeedRows;
2119
+ exports.backfillFeedProvenance = backfillFeedProvenance;
2027
2120
  exports.buildStatementTree = buildStatementTree;
2028
2121
  exports.canvasRouteSlug = canvasRouteSlug;
2029
- exports.catalogForChunkId = catalogForChunkId;
2030
2122
  exports.composeNoteMarkdown = composeNoteMarkdown;
2031
2123
  exports.createIRFile = createIRFile;
2032
2124
  exports.csvToEquipmentLabels = csvToEquipmentLabels;
@@ -2038,11 +2130,14 @@ exports.equipmentToCsv = equipmentToCsv;
2038
2130
  exports.equipmentToMarkdown = equipmentToMarkdown;
2039
2131
  exports.extractNoteIdentity = extractNoteIdentity;
2040
2132
  exports.extractTypedTags = extractTypedTags;
2133
+ exports.feedIdOfMetaKey = feedIdOfMetaKey;
2041
2134
  exports.getRegisteredLanguagePacks = getRegisteredLanguagePacks;
2042
2135
  exports.inMemoryEventStore = inMemoryEventStore;
2043
2136
  exports.injectIdentityFrontmatter = injectIdentityFrontmatter;
2044
2137
  exports.isIRFile = isIRFile;
2045
2138
  exports.listLanguagePacks = listLanguagePacks;
2139
+ exports.migrateNotebookVocabulary = migrateNotebookVocabulary;
2140
+ exports.notebookSlugForChunkId = notebookSlugForChunkId;
2046
2141
  exports.parseCsvLine = parseCsvLine;
2047
2142
  exports.readFrontmatterMeta = readFrontmatterMeta;
2048
2143
  exports.registerLanguagePack = registerLanguagePack;