@bitcobblers/wod-wiki-engine 0.35.2117 → 0.35.2120

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/bin/wod.cjs CHANGED
@@ -342,6 +342,7 @@ function writeBuildReport(outDir, data) {
342
342
  <dt>total</dt><dd>${totalMs} ms</dd>
343
343
  <dt>corpus scan + partition</dt><dd>${passMs.scan} ms (${fileCount} files)</dd>
344
344
  <dt>block-index derivation</dt><dd>${passMs.blockIndex} ms</dd>
345
+ <dt>block syntax gate</dt><dd>${passMs.parseGate} ms</dd>
345
346
  <dt>block-efforts derivation</dt><dd>${passMs.blockEfforts} ms</dd>
346
347
  <dt>chunk writes</dt><dd>${passMs.write} ms</dd>
347
348
  </dl>
@@ -378,7 +379,8 @@ __export(compiler_exports, {
378
379
  loadExistingEffortMap: () => loadExistingEffortMap,
379
380
  partitionIntoChunks: () => partitionIntoChunks,
380
381
  scaffoldDiscoveredEfforts: () => scaffoldDiscoveredEfforts,
381
- validateDashboardNote: () => validateDashboardNote
382
+ validateDashboardNote: () => validateDashboardNote,
383
+ validateWodBlockSyntax: () => validateWodBlockSyntax
382
384
  });
383
385
  function listMarkdownFiles(dir, prefix = "") {
384
386
  if (!fs.existsSync(dir)) return [];
@@ -506,6 +508,26 @@ function buildBlockIndexRows(markdownDir, corpusRoot) {
506
508
  }
507
509
  return rows;
508
510
  }
511
+ function validateWodBlockSyntax(blocks) {
512
+ const problems = [];
513
+ for (const block of blocks) {
514
+ if (block.dataType !== "wod" || !block.rawContent?.trim()) continue;
515
+ const section = wodWikiCore.parseDocumentSections(block.rawContent, { registeredWidgets: SEED_REGISTERED_WIDGETS }).find((s) => s.scriptBlock);
516
+ const source = section?.scriptBlock?.content ?? block.rawContent;
517
+ if (!source.trim()) continue;
518
+ const doc = source.endsWith("\n") ? source : source + "\n";
519
+ const tree = wodWikiLang.whiteboardParser.parse(doc);
520
+ tree.iterate({
521
+ enter: (node) => {
522
+ if (!node.type.isError) return;
523
+ const line = doc.slice(0, node.from).split("\n").length;
524
+ const snippet = source.slice(node.from, Math.min(node.to, node.from + 60)).split("\n")[0];
525
+ problems.push(`${block.sourcePath ?? block.noteId}:${line} \`${snippet}\``);
526
+ }
527
+ });
528
+ }
529
+ return problems;
530
+ }
509
531
  function formatDiscoveredLabel(raw) {
510
532
  const clean = raw.replace(/[-_]+/g, " ").trim();
511
533
  return clean.split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
@@ -628,7 +650,7 @@ function sha256Hex(data) {
628
650
  }
629
651
  function generateSeed(options = {}) {
630
652
  const t0 = Date.now();
631
- const passMs = { scan: 0, blockIndex: 0, blockEfforts: 0, write: 0 };
653
+ const passMs = { scan: 0, blockIndex: 0, parseGate: 0, blockEfforts: 0, write: 0 };
632
654
  const corpusRoot = options.corpusRoot ?? process.cwd();
633
655
  const markdownDir = options.markdownDir ?? path.join(corpusRoot, "markdown");
634
656
  const outDir = options.outDir ?? path.join(corpusRoot, "dist");
@@ -648,13 +670,23 @@ function generateSeed(options = {}) {
648
670
  groups.push({ id: TEMPLATE_CHUNK_ID, files: [templateRowPath] });
649
671
  }
650
672
  passMs.scan = Date.now() - tScan;
673
+ const tBlockIndex = Date.now();
674
+ const blockRows = buildBlockIndexRows(markdownDir, corpusRoot);
675
+ passMs.blockIndex = Date.now() - tBlockIndex;
676
+ const tParseGate = Date.now();
677
+ const syntaxProblems = validateWodBlockSyntax(blockRows);
678
+ passMs.parseGate = Date.now() - tParseGate;
679
+ if (syntaxProblems.length > 0) {
680
+ const shown = syntaxProblems.slice(0, 20).map((p) => ` ${p}`).join("\n");
681
+ const more = syntaxProblems.length > 20 ? `
682
+ \u2026 and ${syntaxProblems.length - 20} more` : "";
683
+ throw new Error(`[wod build] block syntax gate failed \u2014 ${syntaxProblems.length} block(s) do not parse:
684
+ ${shown}${more}`);
685
+ }
651
686
  const chunksDir = path.join(outDir, "chunks");
652
687
  fs.rmSync(outDir, { recursive: true, force: true });
653
688
  fs.mkdirSync(chunksDir, { recursive: true });
654
689
  const manifestChunks = [];
655
- const tBlockIndex = Date.now();
656
- const blockRows = buildBlockIndexRows(markdownDir, corpusRoot);
657
- passMs.blockIndex = Date.now() - tBlockIndex;
658
690
  const tBlockEfforts = Date.now();
659
691
  const effortRows = buildBlockEffortRows(markdownDir, corpusRoot, blockRows);
660
692
  passMs.blockEfforts = Date.now() - tBlockEfforts;
@@ -2319,7 +2351,7 @@ async function putChanged(store, values, keys) {
2319
2351
  async function applySeedChunk(storage, write) {
2320
2352
  assertSeedManifest(write.manifest);
2321
2353
  assertSeedRows(write.rows);
2322
- const result = { totalNotes: 0, totalEfforts: 0, totalBlocks: 0, skippedUserOwned: 0, deleted: 0 };
2354
+ const result = { totalNotes: 0, totalEfforts: 0, totalBlocks: 0, skippedUserOwned: 0, deleted: 0, addedNotes: 0, updatedNotes: 0 };
2323
2355
  const ids = await Promise.all(write.rows.map((row) => seedNoteId(row.path)));
2324
2356
  const pagesBySlug = /* @__PURE__ */ new Map();
2325
2357
  const linkIds = /* @__PURE__ */ new Map();
@@ -2374,6 +2406,8 @@ async function applySeedChunk(storage, write) {
2374
2406
  result.skippedUserOwned++;
2375
2407
  continue;
2376
2408
  }
2409
+ if (!existing) result.addedNotes++;
2410
+ else if (existing.rawContent !== row.content) result.updatedNotes++;
2377
2411
  wodWikiCore.validateNoteBlocks(row.content, row.blocks, 1, { registeredWidgets: SEED_REGISTERED_WIDGETS });
2378
2412
  const sourceRevision = existing ? existing.sourceRevision + (existing.rawContent === row.content ? 0 : 1) : 1;
2379
2413
  let ordinal = 0;