@bitcobblers/wod-wiki-engine 0.35.2128 → 0.36.2130
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 +758 -194
- package/dist/bin/wod.cjs.map +1 -1
- package/dist/bin/wod.d.cts +1 -1
- package/dist/bin/wod.d.ts +1 -1
- package/dist/bin/wod.mjs +5 -3
- package/dist/bin/wod.mjs.map +1 -1
- package/dist/chunk-6L5ZDZJ7.mjs +15 -0
- package/dist/chunk-6L5ZDZJ7.mjs.map +1 -0
- package/dist/{chunk-Y6WO6MXS.mjs → chunk-BMHE7DDG.mjs} +3 -9
- package/dist/chunk-BMHE7DDG.mjs.map +1 -0
- package/dist/chunk-EUQWEX6Z.mjs +253 -0
- package/dist/chunk-EUQWEX6Z.mjs.map +1 -0
- package/dist/{chunk-N4KFWY6Z.mjs → chunk-UKBQ36RW.mjs} +377 -193
- package/dist/chunk-UKBQ36RW.mjs.map +1 -0
- package/dist/{compiler-SXUCF7AU.mjs → compiler-NODHKWJJ.mjs} +4 -3
- package/dist/compiler-NODHKWJJ.mjs.map +1 -0
- package/dist/index.cjs +763 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -8
- package/dist/index.d.ts +27 -8
- package/dist/index.mjs +10 -8
- package/dist/index.mjs.map +1 -1
- package/dist/server/app.cjs +299 -0
- package/dist/server/app.cjs.map +1 -0
- package/dist/server/app.d.cts +24 -0
- package/dist/server/app.d.ts +24 -0
- package/dist/server/app.mjs +301 -0
- package/dist/server/app.mjs.map +1 -0
- package/dist/server-4P6AJAGT.mjs +128 -0
- package/dist/server-4P6AJAGT.mjs.map +1 -0
- package/dist/web/playground/ai-skills/parse.md +656 -0
- package/dist/web/playground/assets/main-Bhn9NHgQ.css +2 -0
- package/dist/web/playground/assets/main-CGSJY1vM.js +212 -0
- package/dist/web/playground/assets/rolldown-runtime-C0FnF6B9.js +1 -0
- package/dist/web/playground/assets/statementBuilderFlow-PTgOOzz5.js +2 -0
- package/dist/web/playground/assets/vendor-BlJqgFME.js +201 -0
- package/dist/web/playground/assets/vendor-codemirror-BtJgoBjf.js +40 -0
- package/dist/web/playground/fonts/Inter-Regular.woff2 +0 -0
- package/dist/web/playground/fonts/Inter-SemiBold.woff2 +0 -0
- package/dist/web/playground/images/hero/editing.png +0 -0
- package/dist/web/playground/images/hero/journal.png +0 -0
- package/dist/web/playground/images/hero/results.png +0 -0
- package/dist/web/playground/images/hero/timer.png +0 -0
- package/dist/web/playground/images/wod-wiki-logo-dark.png +0 -0
- package/dist/web/playground/images/wod-wiki-logo-light.png +0 -0
- package/dist/web/playground/index.html +60 -0
- package/dist/web/playground/seed/core/chunks/canvas.e6c77ad0.json +1 -0
- package/dist/web/playground/seed/core/chunks/template.e5e0e82d.json +1 -0
- package/dist/web/playground/seed/core/manifest.json +24 -0
- package/dist/web/playground/seed/core/report.html +43 -0
- package/dist/web/server/ai-skills/parse.md +656 -0
- package/dist/web/server/assets/main-Bhn9NHgQ.css +2 -0
- package/dist/web/server/assets/main-DhN2J5Ax.js +211 -0
- package/dist/web/server/assets/rolldown-runtime-C0FnF6B9.js +1 -0
- package/dist/web/server/assets/statementBuilderFlow-Dj0o2Wpk.js +2 -0
- package/dist/web/server/assets/vendor-BlJqgFME.js +201 -0
- package/dist/web/server/assets/vendor-codemirror-BtJgoBjf.js +40 -0
- package/dist/web/server/fonts/Inter-Regular.woff2 +0 -0
- package/dist/web/server/fonts/Inter-SemiBold.woff2 +0 -0
- package/dist/web/server/images/hero/editing.png +0 -0
- package/dist/web/server/images/hero/journal.png +0 -0
- package/dist/web/server/images/hero/results.png +0 -0
- package/dist/web/server/images/hero/timer.png +0 -0
- package/dist/web/server/images/wod-wiki-logo-dark.png +0 -0
- package/dist/web/server/images/wod-wiki-logo-light.png +0 -0
- package/dist/web/server/index.html +60 -0
- package/dist/web/server/seed/core/chunks/canvas.e6c77ad0.json +1 -0
- package/dist/web/server/seed/core/chunks/template.e5e0e82d.json +1 -0
- package/dist/web/server/seed/core/manifest.json +24 -0
- package/dist/web/server/seed/core/report.html +43 -0
- package/package.json +11 -5
- package/dist/chunk-N4KFWY6Z.mjs.map +0 -1
- package/dist/chunk-Y6WO6MXS.mjs.map +0 -1
- package/dist/compiler-SXUCF7AU.mjs.map +0 -1
package/dist/bin/wod.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env -S bun --no-env-file
|
package/dist/bin/wod.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env -S bun --no-env-file
|
package/dist/bin/wod.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env -S bun --no-env-file
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
|
-
import { cliMain } from '../chunk-
|
|
4
|
-
import '../chunk-
|
|
3
|
+
import { cliMain } from '../chunk-UKBQ36RW.mjs';
|
|
4
|
+
import '../chunk-BMHE7DDG.mjs';
|
|
5
|
+
import '../chunk-EUQWEX6Z.mjs';
|
|
6
|
+
import '../chunk-6L5ZDZJ7.mjs';
|
|
5
7
|
|
|
6
8
|
if (typeof globalThis.require === 'undefined') {
|
|
7
9
|
try { globalThis.require = createRequire(import.meta.url); } catch {}
|
package/dist/bin/wod.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/wod.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/bin/wod.ts"],"names":[],"mappings":";;;;;;;;;;;;AAcA,KAAA,CAAM,YAAY;AAChB,EAAA,MAAM,WAAW,MAAM,OAAA,CAAQ,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACpD,EAAA,OAAA,CAAQ,QAAA,GAAW,QAAA;AACrB,CAAA,GAAG","file":"wod.mjs","sourcesContent":["#!/usr/bin/env -S bun --no-env-file\n/**\n * wod CLI Entry Point\n *\n * Dispatches to cliMain(process.argv.slice(2)).\n * Runs natively under Bun (shebang; --no-env-file keeps .env loading in the\n * CLI's own loader so flag > process env > .env precedence stays in one place)\n * and as a compiled node binary after tsup bundle (explicit\n * `node dist/bin/wod.mjs …` remains supported for SQLite/Turso on Node;\n * serve/playground require Bun).\n */\n\nimport { cliMain } from '../cli/runner';\n\nvoid (async () => {\n const exitCode = await cliMain(process.argv.slice(2));\n process.exitCode = exitCode;\n})();\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
|
|
3
|
+
if (typeof globalThis.require === 'undefined') {
|
|
4
|
+
try { globalThis.require = createRequire(import.meta.url); } catch {}
|
|
5
|
+
}
|
|
6
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
7
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
8
|
+
}) : x)(function(x) {
|
|
9
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export { __require };
|
|
14
|
+
//# sourceMappingURL=chunk-6L5ZDZJ7.mjs.map
|
|
15
|
+
//# sourceMappingURL=chunk-6L5ZDZJ7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-6L5ZDZJ7.mjs"}
|
|
@@ -5,12 +5,6 @@ import { KNOWN_SECTION_WIDGETS } from '@bitcobblers/wod-wiki-core';
|
|
|
5
5
|
if (typeof globalThis.require === 'undefined') {
|
|
6
6
|
try { globalThis.require = createRequire(import.meta.url); } catch {}
|
|
7
7
|
}
|
|
8
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
-
}) : x)(function(x) {
|
|
11
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
-
});
|
|
14
8
|
|
|
15
9
|
// src/cli/seedbuild/frontmatter.ts
|
|
16
10
|
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
|
|
@@ -182,6 +176,6 @@ function seedNoteSourceId(path, content, chunkId) {
|
|
|
182
176
|
return void 0;
|
|
183
177
|
}
|
|
184
178
|
|
|
185
|
-
export { CANVAS_CHUNK_ID, DASHBOARDS_CHUNK_ID, EFFORTS_CHUNK_ID, SEED_BROADCAST_CHANNEL, SEED_REGISTERED_WIDGETS, SEED_SCHEMA, TEMPLATE_CHUNK_ID,
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
187
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
export { CANVAS_CHUNK_ID, DASHBOARDS_CHUNK_ID, EFFORTS_CHUNK_ID, SEED_BROADCAST_CHANNEL, SEED_REGISTERED_WIDGETS, SEED_SCHEMA, TEMPLATE_CHUNK_ID, canvasRouteSlug, catalogForChunkId, emptySeedMeta, parseEffortFile, parseFrontmatter, seedMetaKey, seedNoteSourceId };
|
|
180
|
+
//# sourceMappingURL=chunk-BMHE7DDG.mjs.map
|
|
181
|
+
//# sourceMappingURL=chunk-BMHE7DDG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/seedbuild/frontmatter.ts","../src/cli/seedbuild/effort-file.ts","../src/cli/seedbuild/contract.ts"],"names":[],"mappings":"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","file":"chunk-BMHE7DDG.mjs","sourcesContent":["/**\n * Frontmatter parser — port of wod-wiki's apps/playground/src/lib/frontmatter.ts\n * (parseFrontmatter/getScalar/getList only; the editor-only helpers\n * (LinkWidget, YouTube, serialize) stay in the app).\n *\n * ponytail: semantics must match the app's parser exactly — the seed\n * compiler and the app runtime derive frontmatter from the same corpus.\n * Upgrade path: publish the parser in @bitcobblers/wod-wiki-core and import\n * from both sides.\n */\n\nexport interface ParsedFrontmatter {\n meta: Record<string, string | number | string[]>\n body: string\n}\n\n/** Leading `---` … `---` block; body is everything after the closing delimiter. */\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/;\n\n/** Strip matched wrapping quotes: `\"x\"` / `'x'` → `x`; mismatched quotes are kept.\n * Double-quoted values also collapse the serializer's escapes (`\\\\\"`, `\\\\\\\\`). */\nfunction unquote(value: string): string {\n return value.replace(/^(['\"])(.*)\\1$/, (_match, quote: string, inner: string) =>\n quote === '\"' ? inner.replace(/\\\\([\"\\\\])/g, '$1') : inner,\n );\n}\n\n/**\n * Parse the leading YAML frontmatter block of a markdown string.\n *\n * Semantics (mirrors the app):\n * - Scalar `key: value` (key `/^[A-Za-z][\\w.-]*$/`, dots allow flat nested\n * keys like `book.title`): wrapping quotes stripped; bare numeric strings\n * become `number`, quoted scalars always stay strings.\n * - `key:` with empty value followed by indented `- item` lines → `string[]`.\n * - `key:` with empty value and no list items → `''`.\n * - Inline `key: [a, b]` stays a plain scalar string.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = raw.match(FRONTMATTER_RE);\n if (!match) return { meta: {}, body: raw };\n return { meta: parseMetaLines(match[1].split(/\\r?\\n/)), body: raw.slice(match[0].length) };\n}\n\nfunction parseMetaLines(lines: string[]): ParsedFrontmatter['meta'] {\n const meta: ParsedFrontmatter['meta'] = {};\n\n for (let i = 0; i < lines.length; i++) {\n const keyMatch = lines[i].match(/^([A-Za-z][\\w.-]*)\\s*:(.*)$/);\n if (!keyMatch) continue; // indented/nested/list lines are not top-level keys\n\n const key = keyMatch[1];\n const rawVal = keyMatch[2].trim();\n\n if (rawVal === '') {\n const items: string[] = [];\n while (i + 1 < lines.length) {\n const itemMatch = lines[i + 1].match(/^\\s+-\\s+(.+)$/);\n if (!itemMatch) break;\n items.push(itemMatch[1].trim());\n i++;\n }\n meta[key] = items.length > 0 ? items : '';\n } else {\n const wasQuoted = /^(['\"])(.*)\\1$/.test(rawVal);\n const value = unquote(rawVal);\n const num = Number(value);\n meta[key] = !wasQuoted && value !== '' && !isNaN(num) ? num : value;\n }\n }\n\n return meta;\n}\n\n/** Scalar value at `key`, or `undefined` when absent or a list. */\nexport function getScalar(\n meta: ParsedFrontmatter['meta'],\n key: string,\n): string | number | undefined {\n const value = meta[key];\n return typeof value === 'string' || typeof value === 'number' ? value : undefined;\n}\n\n/** List value at `key`, or `[]` when absent or a scalar. */\nexport function getList(meta: ParsedFrontmatter['meta'], key: string): string[] {\n const value = meta[key];\n return Array.isArray(value) ? value : [];\n}\n","/**\n * Effort-file parsing — port of wod-wiki's\n * apps/playground/src/repositories/effort-markdown.ts (parse-frontmatter\n * direction only; effortToDocument/documentToEffort stay in the app).\n *\n * The compiler needs `parseEffortFile` to build the effort alias map used by\n * block-efforts row derivation. Semantics MUST match the app's runtime effort\n * materialization — alias/slug drift would desync the block plane from the\n * note plane.\n *\n * ponytail: duplicated rather than package-shared to keep this repo\n * standalone; upgrade path is the same published effort-format module\n * imported by both sides.\n */\nimport {\n isEffortDiscipline,\n type IEffort,\n type EffortRegistrySource,\n type IntensityTier,\n} from '@bitcobblers/wod-wiki-lang';\nimport { parseFrontmatter, getScalar, getList } from './frontmatter';\n\n/** Validate a parsed discipline against the canonical vocabulary. */\nfunction parseDiscipline(val: string | undefined): IEffort['baseAttributes']['discipline'] {\n if (!val) return undefined;\n const normalized = unquoteYaml(val.trim()).toLowerCase();\n if (isEffortDiscipline(normalized)) return normalized as IEffort['baseAttributes']['discipline'];\n console.warn(`[effort-file] unknown discipline '${val}' — treating as unset`);\n return undefined;\n}\n\nfunction unquoteYaml(val: string): string {\n if (val.startsWith('\"') && val.endsWith('\"')) {\n return val.slice(1, -1).replace(/\\\\([\"\\\\])/g, '$1');\n }\n if (val.startsWith(\"'\") && val.endsWith(\"'\")) {\n return val.slice(1, -1).replace(/\\\\'/g, \"'\");\n }\n return val;\n}\n\n/** Coerce a scalar from a nested block: booleans/numbers are coerced; everything else stays a string. */\nfunction coerceNestedScalar(raw: string): unknown {\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n if (raw !== '' && !Number.isNaN(Number(raw))) return Number(raw);\n return raw;\n}\n\n/**\n * Read a nested (`key:` followed by indented entries) section from frontmatter\n * lines. Two levels are supported (`derivation.coefficients.*`).\n */\nfunction readNestedSection(lines: string[], key: string): Record<string, unknown> | undefined {\n const start = lines.findIndex(l => new RegExp(`^${key}:\\\\s*$`).test(l));\n if (start === -1) return undefined;\n\n const result: Record<string, unknown> = {};\n let subKey: string | null = null;\n\n for (let i = start + 1; i < lines.length; i++) {\n const line = lines[i];\n if (/^\\S/.test(line)) break; // next top-level key ends the block\n\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const indent = line.length - line.trimStart().length;\n const m = trimmed.match(/^([\\w.-]+):\\s*(.*)$/);\n if (!m) continue;\n const [, k, rawVal] = m;\n\n if (indent === 2) {\n if (rawVal === '') {\n subKey = k;\n result[k] = {};\n } else {\n subKey = null;\n result[k] = coerceNestedScalar(rawVal);\n }\n } else if (indent >= 4 && subKey !== null) {\n (result[subKey] as Record<string, unknown>)[k] = coerceNestedScalar(rawVal);\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n/** Parse a single bundled effort markdown file into an IEffort (null when malformed). */\nexport function parseEffortFile(raw: string): IEffort | null {\n const blockMatch = raw.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (!blockMatch) return null;\n\n const { meta, body } = parseFrontmatter(raw);\n const innerLines = blockMatch[1].split(/\\r?\\n/);\n\n const id = getScalar(meta, 'id');\n const slug = getScalar(meta, 'slug');\n const label = getScalar(meta, 'label');\n const aliases = getList(meta, 'aliases');\n\n const baseAttrs = readNestedSection(innerLines, 'baseAttributes');\n const hints = readNestedSection(innerLines, 'hints');\n const derivation = readNestedSection(innerLines, 'derivation');\n\n const metRaw = baseAttrs?.met;\n const met = typeof metRaw === 'number' ? metRaw : Number(metRaw);\n if (!id || !slug || !label || metRaw === undefined || Number.isNaN(met)) return null;\n\n const discipline = parseDiscipline(\n typeof baseAttrs?.discipline === 'string' ? baseAttrs.discipline : undefined,\n );\n const intensityTier = baseAttrs?.intensityTier;\n const trimmedBody = body.trim();\n\n return {\n id: String(id),\n slug: String(slug),\n label: String(label),\n aliases,\n baseAttributes: {\n met,\n ...(discipline ? { discipline } : {}),\n ...(intensityTier ? { intensityTier: intensityTier as IntensityTier } : {}),\n },\n registrySource: 'bundled' as EffortRegistrySource,\n ...(trimmedBody ? { body: trimmedBody } : {}),\n ...(hints ? { hints } : {}),\n ...(derivation ? { derivation: derivation as IEffort['derivation'] } : {}),\n };\n}\n","import type { BlockEffort, BlockIndexRow, NoteBlock } from '@bitcobblers/wod-wiki-core';\nimport { KNOWN_SECTION_WIDGETS } from '@bitcobblers/wod-wiki-core';\n\nexport const SEED_SCHEMA = 8;\nexport const SEED_REGISTERED_WIDGETS = KNOWN_SECTION_WIDGETS;\n\n/** Source and all current derived rows commit as one chunk. */\nexport interface SeedRow {\n path: string;\n content: string;\n blocks: Record<string, NoteBlock>;\n blockIndex: BlockIndexRow[];\n blockEfforts: BlockEffort[];\n}\n\nexport type ChunkKind = 'notes';\nexport interface ManifestChunk {\n id: string;\n path: string;\n sha256: string;\n bytes: number;\n count: number;\n kind?: ChunkKind;\n}\nexport interface SeedManifest {\n schema: number;\n version: number;\n versionLabel?: string;\n commit?: string;\n dirty?: boolean;\n builtAt: string;\n chunks: ManifestChunk[];\n}\nexport interface SeedMetaRecord {\n key: string;\n schema: number;\n seedVersion: number;\n builtAt: string;\n importedAt: number;\n chunks: Record<string, { sha256: string; noteIds?: string[] }>;\n claim?: { owner: string; at: number } | null;\n}\nexport const SEED_BROADCAST_CHANNEL = 'wodwiki.seed';\nexport const EFFORTS_CHUNK_ID = 'efforts';\nexport const CANVAS_CHUNK_ID = 'canvas';\nexport const DASHBOARDS_CHUNK_ID = 'dashboards';\nexport const TEMPLATE_CHUNK_ID = 'template';\nexport function seedMetaKey(sourceId: string): string { return `seed:${sourceId}`; }\nexport function emptySeedMeta(key: string): SeedMetaRecord {\n return { key, schema: SEED_SCHEMA, seedVersion: 0, builtAt: '', importedAt: 0, chunks: {}, claim: null };\n}\nexport function catalogForChunkId(chunkId: string): string | undefined {\n const value = /^(?:collection|feed)\\.(.+)$/.exec(chunkId)?.[1];\n return value && value !== '_root' ? value : undefined;\n}\nexport function canvasRouteSlug(content: string): string | null {\n const fm = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(content);\n if (fm?.[1] && !/^template:\\s*canvas\\s*$/m.test(fm[1])) return null;\n return fm?.[1]?.match(/^route:\\s*(\\S+)\\s*$/m)?.[1]?.replace(/^\\//, '') || null;\n}\nexport function seedNoteSourceId(path: string, content: string, chunkId: string): string | undefined {\n const parts = path.split('/');\n const stem = (parts.at(-1) ?? '').replace(/\\.md$/i, '');\n const under = parts.slice(2).map((p) => p.replace(/\\.md$/i, '')).join('/');\n if (chunkId === CANVAS_CHUNK_ID) return `guides:${canvasRouteSlug(content) ?? under}`;\n if (chunkId === DASHBOARDS_CHUNK_ID) return 'dashboards';\n if (chunkId === EFFORTS_CHUNK_ID) return 'efforts';\n if (chunkId === TEMPLATE_CHUNK_ID) return 'playground';\n if (chunkId.startsWith('collection.')) {\n const catalog = catalogForChunkId(chunkId);\n return !catalog ? 'collection:_root' : stem.toLowerCase() === 'readme' ? `collection:${catalog}` : `collection:${catalog}/${stem}`;\n }\n if (chunkId.startsWith('feed.')) return `feed:feeds/${under}`;\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { __require } from './chunk-6L5ZDZJ7.mjs';
|
|
3
|
+
import { bundledEfforts } from '@bitcobblers/wod-wiki-lang';
|
|
4
|
+
|
|
5
|
+
if (typeof globalThis.require === 'undefined') {
|
|
6
|
+
try { globalThis.require = createRequire(import.meta.url); } catch {}
|
|
7
|
+
}
|
|
8
|
+
var nodePath = () => nodeRequire()("node:path");
|
|
9
|
+
var nodeFs = () => nodeRequire()("node:fs");
|
|
10
|
+
var nodeCrypto = () => nodeRequire()("node:crypto");
|
|
11
|
+
function nodeRequire() {
|
|
12
|
+
const g = globalThis;
|
|
13
|
+
if (typeof g.process?.versions?.node === "undefined" && typeof g.Bun === "undefined") {
|
|
14
|
+
throw new Error("SQLite operations are only supported in Node / Bun environments");
|
|
15
|
+
}
|
|
16
|
+
const req = g.require ?? (typeof __require === "function" ? __require : void 0);
|
|
17
|
+
if (!req) throw new Error("SQLite operations require a CJS require shim (missing tsup banner?)");
|
|
18
|
+
return req;
|
|
19
|
+
}
|
|
20
|
+
var sqlModulePromise;
|
|
21
|
+
function loadSql() {
|
|
22
|
+
sqlModulePromise ??= import(
|
|
23
|
+
/* @vite-ignore */
|
|
24
|
+
'@bitcobblers/wod-wiki-storage/sql'
|
|
25
|
+
);
|
|
26
|
+
return sqlModulePromise;
|
|
27
|
+
}
|
|
28
|
+
function resolveDbPath(dbPath) {
|
|
29
|
+
const chosen = dbPath ?? process.env.WOD_WIKI_DB ?? "./wodwiki.db";
|
|
30
|
+
return nodePath().resolve(process.cwd(), chosen);
|
|
31
|
+
}
|
|
32
|
+
async function openCliDb(target, opts) {
|
|
33
|
+
if (target === void 0 || typeof target === "string") {
|
|
34
|
+
return openSqliteDb(resolveDbPath(target), opts);
|
|
35
|
+
}
|
|
36
|
+
switch (target.kind) {
|
|
37
|
+
case "sqlite":
|
|
38
|
+
return openSqliteDb(target.path, opts);
|
|
39
|
+
case "turso":
|
|
40
|
+
return openRemoteDb(
|
|
41
|
+
{ DB_DRIVER: "turso", DATABASE_URL: target.url, LIBSQL_AUTH_TOKEN: target.authToken },
|
|
42
|
+
target.label,
|
|
43
|
+
opts
|
|
44
|
+
);
|
|
45
|
+
case "postgres":
|
|
46
|
+
return openRemoteDb({ DB_DRIVER: "postgres", DATABASE_URL: target.url }, target.label, opts);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function openSqliteDb(resolved, opts) {
|
|
50
|
+
const [{ createClient }, sql] = await Promise.all([
|
|
51
|
+
import(
|
|
52
|
+
/* @vite-ignore */
|
|
53
|
+
'@libsql/client'
|
|
54
|
+
),
|
|
55
|
+
loadSql()
|
|
56
|
+
]);
|
|
57
|
+
const initialize = opts?.initialize ?? true;
|
|
58
|
+
if (!initialize && !nodeFs().existsSync(resolved)) {
|
|
59
|
+
throw new Error(`[wod] no database at ${resolved} \u2014 run \`wod init\` to create and initialize it`);
|
|
60
|
+
}
|
|
61
|
+
if (initialize) nodeFs().mkdirSync(nodePath().dirname(resolved), { recursive: true });
|
|
62
|
+
const db = sql.libsqlDatabase(createClient({ url: `file:${resolved}` }));
|
|
63
|
+
try {
|
|
64
|
+
if (initialize) {
|
|
65
|
+
await sql.initializeStore(db);
|
|
66
|
+
await sql.initializeDomain(db);
|
|
67
|
+
} else {
|
|
68
|
+
await sql.verifyReadiness(db).catch((error) => {
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
throw new Error(`${message} \u2014 run \`wod init\` to initialize it`, { cause: error });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return { db, storage: new sql.SqlStorage(db), path: resolved, close: () => db.close() };
|
|
74
|
+
} catch (error) {
|
|
75
|
+
await db.close();
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function openRemoteDb(env, label, opts) {
|
|
80
|
+
const [{ openDatabase }, sql] = await Promise.all([
|
|
81
|
+
import(
|
|
82
|
+
/* @vite-ignore */
|
|
83
|
+
'@bitcobblers/wod-wiki-storage/sql/node'
|
|
84
|
+
),
|
|
85
|
+
loadSql()
|
|
86
|
+
]);
|
|
87
|
+
let db;
|
|
88
|
+
try {
|
|
89
|
+
db = await openDatabase(env, { create: opts?.create });
|
|
90
|
+
if (opts?.initialize === false) {
|
|
91
|
+
await sql.verifyReadiness(db);
|
|
92
|
+
} else {
|
|
93
|
+
await sql.initializeStore(db);
|
|
94
|
+
await sql.initializeDomain(db);
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
await db?.close().catch(() => {
|
|
98
|
+
});
|
|
99
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
100
|
+
throw new Error(
|
|
101
|
+
`[wod] ${label}: ${message}${opts?.initialize === false ? " \u2014 run `wod init` to initialize it" : ""}`,
|
|
102
|
+
{ cause: error }
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return { db, storage: new sql.SqlStorage(db), path: label, close: () => db.close() };
|
|
106
|
+
}
|
|
107
|
+
function formatV5Digest(digest) {
|
|
108
|
+
const bytes = digest.slice(0, 16);
|
|
109
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
110
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
111
|
+
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0"));
|
|
112
|
+
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
|
|
113
|
+
}
|
|
114
|
+
function uuid5(namespace, name) {
|
|
115
|
+
return formatV5Digest(nodeCrypto().createHash("sha1").update(namespace).update(name).digest());
|
|
116
|
+
}
|
|
117
|
+
var CLI_UUID_NAMESPACE = "c0ffee00-8b1a-4e2c-9d3f-5a6b7c8d9e0f";
|
|
118
|
+
function stableNoteId(sourceLabel, content) {
|
|
119
|
+
if (sourceLabel && sourceLabel !== "-") {
|
|
120
|
+
return uuid5(CLI_UUID_NAMESPACE, `wod-cli:${nodePath().resolve(process.cwd(), sourceLabel)}`);
|
|
121
|
+
}
|
|
122
|
+
return uuid5(CLI_UUID_NAMESPACE, `wod-cli:stdin:${content.length}:${content.slice(0, 256)}`);
|
|
123
|
+
}
|
|
124
|
+
function randomId() {
|
|
125
|
+
return nodeCrypto().randomUUID();
|
|
126
|
+
}
|
|
127
|
+
async function allRows(sql, db, store) {
|
|
128
|
+
return sql.listRows(db, sql.storeDefinition(store));
|
|
129
|
+
}
|
|
130
|
+
async function rowsByIndex(sql, db, store, index, only) {
|
|
131
|
+
return sql.listRows(db, sql.storeDefinition(store), { only }, void 0, index);
|
|
132
|
+
}
|
|
133
|
+
function sqliteEventStore(db) {
|
|
134
|
+
const all = async () => await allRows(await loadSql(), db, "events");
|
|
135
|
+
return {
|
|
136
|
+
getEventsByTimeRange: async (start, end) => (await all()).filter((r) => r.timestamp >= start && r.timestamp <= end),
|
|
137
|
+
getEventsByResult: async (resultId) => (await all()).filter((r) => r.resultId === resultId),
|
|
138
|
+
getEventsForNote: async (noteId) => (await all()).filter((r) => r.noteId === noteId),
|
|
139
|
+
getEventsByContent: async (blockContentId) => (await all()).filter((r) => r.blockContentId === blockContentId),
|
|
140
|
+
scanAll: all,
|
|
141
|
+
appendEvents: async (appended) => {
|
|
142
|
+
const sql = await loadSql();
|
|
143
|
+
await db.transaction(async (tx) => {
|
|
144
|
+
const eventsDef = sql.storeDefinition("events");
|
|
145
|
+
for (const row of appended) await sql.putRow(tx, eventsDef, row);
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
finalizeSummaries: async (resultId, finals) => {
|
|
149
|
+
const sql = await loadSql();
|
|
150
|
+
await db.transaction(async (tx) => {
|
|
151
|
+
const eventsDef = sql.storeDefinition("events");
|
|
152
|
+
const existing = (await sql.listRows(tx, eventsDef)).filter(
|
|
153
|
+
(r) => r.resultId === resultId && r.grain === "summary" && r.origin !== "user"
|
|
154
|
+
);
|
|
155
|
+
for (const row of existing) await sql.deleteRows(tx, eventsDef, row.id);
|
|
156
|
+
for (const row of finals) await sql.putRow(tx, eventsDef, row);
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
deleteEvents: async (ids) => {
|
|
160
|
+
const sql = await loadSql();
|
|
161
|
+
await db.transaction(async (tx) => {
|
|
162
|
+
const eventsDef = sql.storeDefinition("events");
|
|
163
|
+
for (const id of ids) await sql.deleteRows(tx, eventsDef, id);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function sqliteNoteStore(db) {
|
|
169
|
+
return {
|
|
170
|
+
getAllNotes: async () => await allRows(await loadSql(), db, "notes"),
|
|
171
|
+
getNotesByIds: async (noteIds) => {
|
|
172
|
+
const sql = await loadSql();
|
|
173
|
+
const rows = await sql.getRows(db, sql.storeDefinition("notes"), [...noteIds]);
|
|
174
|
+
return rows.filter((row) => row !== void 0);
|
|
175
|
+
},
|
|
176
|
+
getNoteIdsForTag: async (label) => {
|
|
177
|
+
const sql = await loadSql();
|
|
178
|
+
const tags = (await allRows(sql, db, "tags")).filter((t) => t.label === label);
|
|
179
|
+
const ids = {};
|
|
180
|
+
for (const tag of tags) {
|
|
181
|
+
for (const row of await rowsByIndex(sql, db, "note_tags", "by-tag", tag.id)) {
|
|
182
|
+
ids[row.noteId] = true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return new Set(Object.keys(ids));
|
|
186
|
+
},
|
|
187
|
+
getNoteTagLabels: async (noteId) => {
|
|
188
|
+
const sql = await loadSql();
|
|
189
|
+
const tagRows = await allRows(sql, db, "tags");
|
|
190
|
+
const labelById = {};
|
|
191
|
+
for (const t of tagRows) labelById[t.id] = t.label;
|
|
192
|
+
const links = await rowsByIndex(sql, db, "note_tags", "by-note", noteId);
|
|
193
|
+
return links.map((l) => labelById[l.tagId]).filter((l) => typeof l === "string");
|
|
194
|
+
},
|
|
195
|
+
queryDomain: async (request) => {
|
|
196
|
+
const result = await (await loadSql()).handleDomainQuery(db, request);
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function sqliteBlockStore(db) {
|
|
202
|
+
return {
|
|
203
|
+
getAllBlocks: async () => await allRows(await loadSql(), db, "block_index"),
|
|
204
|
+
queryDomain: async (request) => {
|
|
205
|
+
const result = await (await loadSql()).handleDomainQuery(db, { ...request, plan: "blocks" });
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function sqliteEffortStore(db) {
|
|
211
|
+
return {
|
|
212
|
+
getAllEfforts: async () => {
|
|
213
|
+
const stored = await allRows(await loadSql(), db, "efforts");
|
|
214
|
+
const bySlug = {};
|
|
215
|
+
for (const effort of stored) bySlug[effort.slug] = effort;
|
|
216
|
+
for (const effort of bundledEfforts) {
|
|
217
|
+
bySlug[effort.slug] ??= effort;
|
|
218
|
+
}
|
|
219
|
+
return Object.values(bySlug);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function sqliteIndexStore(db, store) {
|
|
224
|
+
return {
|
|
225
|
+
getAllFromIndex: async (index, key) => rowsByIndex(await loadSql(), db, store, index, key)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
async function getNoteBundle(db, noteId) {
|
|
229
|
+
const sql = await loadSql();
|
|
230
|
+
const note = await sql.getRow(db, sql.storeDefinition("notes"), noteId);
|
|
231
|
+
return { note };
|
|
232
|
+
}
|
|
233
|
+
async function getSessionBundle(db, resultId) {
|
|
234
|
+
const sql = await loadSql();
|
|
235
|
+
const session = await sql.getRow(db, sql.storeDefinition("sessions"), resultId);
|
|
236
|
+
if (!session) return void 0;
|
|
237
|
+
const events = await sql.listRows(db, sql.storeDefinition("events"), { only: resultId }, void 0, "by-result-grain");
|
|
238
|
+
return { session, events };
|
|
239
|
+
}
|
|
240
|
+
async function getEffortBySlug(db, slug) {
|
|
241
|
+
const sql = await loadSql();
|
|
242
|
+
const efforts = await allRows(sql, db, "efforts");
|
|
243
|
+
return efforts.find((e) => e.slug === slug);
|
|
244
|
+
}
|
|
245
|
+
async function listTagsByType(db, type) {
|
|
246
|
+
const sql = await loadSql();
|
|
247
|
+
const tags = await allRows(sql, db, "tags");
|
|
248
|
+
return tags.filter((t) => t.type === type);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export { CLI_UUID_NAMESPACE, getEffortBySlug, getNoteBundle, getSessionBundle, listTagsByType, loadSql, nodeFs, nodePath, openCliDb, randomId, sqliteBlockStore, sqliteEffortStore, sqliteEventStore, sqliteIndexStore, sqliteNoteStore, stableNoteId, uuid5 };
|
|
252
|
+
//# sourceMappingURL=chunk-EUQWEX6Z.mjs.map
|
|
253
|
+
//# sourceMappingURL=chunk-EUQWEX6Z.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/db.ts"],"names":[],"mappings":"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","file":"chunk-EUQWEX6Z.mjs","sourcesContent":["/**\n * Local SQLite seam for the `wod` CLI.\n *\n * Opens a libsql `file:` database, initializes the shared storage schema\n * (KV store tables + domain projections), and adapts the rows into the WQL\n * store interfaces — the same shape the playground builds over IndexedDB.\n *\n * Everything heavy is loaded lazily (`@libsql/client`,\n * `@bitcobblers/wod-wiki-storage/sql`, node `fs`/`crypto`) so browser\n * bundles that import the engine index never pull native drivers; the\n * dynamic specifiers stay external in the CLI bundle.\n */\n\nimport type { EventRecord } from '@bitcobblers/wod-wiki-core';\nimport type { IStorage, KeyDTO, Note, Session } from '@bitcobblers/wod-wiki-storage';\nimport type { RangeDTO, StoreDef } from '@bitcobblers/wod-wiki-storage';\nimport type {\n Database,\n LibsqlClient,\n SqlConnection,\n} from '@bitcobblers/wod-wiki-storage/sql';\nimport type { CliDatabaseConfig } from './config';\nimport type {\n BlockQueryStore,\n EventStore,\n EffortQueryStore,\n NoteQueryStore,\n WqlDomainReadResult,\n} from '@bitcobblers/wod-wiki-wql';\nimport { bundledEfforts } from '@bitcobblers/wod-wiki-lang';\n\n/** Structural CJS require — avoids the deprecated NodeJS namespace type. */\ntype CjsRequire = (id: string) => unknown;\n\n/** Minimal node builtin surfaces the CLI uses (kept out of browser bundles). */\nexport interface PathShim { resolve(...parts: string[]): string; join(...parts: string[]): string; dirname(p: string): string; basename(p: string): string }\nexport interface FsShim {\n mkdirSync(p: string, opts: { recursive: boolean }): void;\n existsSync(p: string): boolean;\n unlinkSync(p: string): void;\n readFileSync(p: string, encoding: string): string;\n writeFileSync(p: string, data: string, encoding: string): void;\n}\nexport interface HashShim { update(data: string): HashShim; digest(): Uint8Array }\nexport interface CryptoShim {\n createHash(algorithm: string): HashShim;\n randomUUID(): string;\n}\nexport const nodePath = (): PathShim => nodeRequire()('node:path') as PathShim;\nexport const nodeFs = (): FsShim => nodeRequire()('node:fs') as FsShim;\nexport const nodeCrypto = (): CryptoShim => nodeRequire()('node:crypto') as CryptoShim;\n\n/** Lazy CJS require — keeps node builtins out of browser bundles. */\nfunction nodeRequire(): CjsRequire {\n const g = globalThis as { process?: { versions?: Record<string, string> }; Bun?: unknown; require?: CjsRequire };\n if (typeof g.process?.versions?.node === 'undefined' && typeof g.Bun === 'undefined') {\n throw new Error('SQLite operations are only supported in Node / Bun environments');\n }\n const req = g.require ?? (typeof require === 'function' ? require : undefined);\n if (!req) throw new Error('SQLite operations require a CJS require shim (missing tsup banner?)');\n return req;\n}\n\n/** The storage/sql surface the CLI uses — structural mirror so the lazy import types check. */\nexport interface SqlApi {\n libsqlDatabase(client: LibsqlClient): Database;\n SqlStorage: new (db: Database) => IStorage;\n initializeStore(db: Database): Promise<void>;\n initializeDomain(db: Database): Promise<void>;\n verifyReadiness(db: Database): Promise<void>;\n storeDefinition(name: string): StoreDef;\n listRows(conn: SqlConnection, def: StoreDef, range?: RangeDTO, count?: number, indexName?: string): Promise<unknown[]>;\n getRow(conn: SqlConnection, def: StoreDef, key: KeyDTO): Promise<unknown | undefined>;\n getRows(conn: SqlConnection, def: StoreDef, keys: KeyDTO[]): Promise<(unknown | undefined)[]>;\n putRow(conn: SqlConnection, def: StoreDef, value: unknown): Promise<unknown>;\n deleteRows(conn: SqlConnection, def: StoreDef, keyOrRange: unknown): Promise<void>;\n refreshDomain(conn: SqlConnection, ops: unknown[]): Promise<unknown>;\n handleDomainQuery(db: Database, body: unknown): Promise<unknown>;\n}\n\nlet sqlModulePromise: Promise<SqlApi> | undefined;\n\n/** Lazily import the storage SQL subpath (kept external in the CLI bundle). */\nexport function loadSql(): Promise<SqlApi> {\n sqlModulePromise ??= import(/* @vite-ignore */ '@bitcobblers/wod-wiki-storage/sql') as Promise<SqlApi>;\n return sqlModulePromise;\n}\n\nexport interface CliDb {\n db: Database;\n storage: IStorage;\n /** Absolute path of the underlying .sqlite file — or the sanitized display\n * label (URL without credentials) for remote backends. */\n path: string;\n close(): Promise<void>;\n}\n\n/**\n * Resolve the effective database path: explicit flag wins, then\n * WOD_WIKI_DB, then ./wodwiki.db in the current working directory.\n */\nexport function resolveDbPath(dbPath?: string): string {\n const chosen = dbPath ?? process.env.WOD_WIKI_DB ?? './wodwiki.db';\n return nodePath().resolve(process.cwd(), chosen);\n}\n\n/**\n * Open the CLI database: a legacy local sqlite path (internal callers,\n * created/initialized as before) or a resolved backend config from ./config.\n *\n * opts.initialize (default true): run the schema + projection\n * initialization. false → verify the schema/projection guards only: a\n * missing local sqlite file is NOT created and yields an actionable\n * `wod init` error; remote targets are only probed, never created.\n *\n * opts.create (explicit init requests only, postgres): when the configured\n * PostgreSQL database is missing, openDatabase creates it through the admin\n * \"postgres\" database before initializing. Turso has no management API —\n * its hosted target must already exist.\n */\nexport async function openCliDb(\n target?: string | CliDatabaseConfig,\n opts?: { initialize?: boolean; create?: boolean },\n): Promise<CliDb> {\n if (target === undefined || typeof target === 'string') {\n return openSqliteDb(resolveDbPath(target), opts);\n }\n switch (target.kind) {\n case 'sqlite':\n return openSqliteDb(target.path, opts);\n case 'turso':\n return openRemoteDb(\n { DB_DRIVER: 'turso', DATABASE_URL: target.url, LIBSQL_AUTH_TOKEN: target.authToken },\n target.label,\n opts,\n );\n case 'postgres':\n return openRemoteDb({ DB_DRIVER: 'postgres', DATABASE_URL: target.url }, target.label, opts);\n }\n}\n\nasync function openSqliteDb(resolved: string, opts?: { initialize?: boolean; create?: boolean }): Promise<CliDb> {\n const [{ createClient }, sql] = await Promise.all([\n import(/* @vite-ignore */ '@libsql/client') as Promise<{ createClient: (config: { url: string }) => LibsqlClient }>,\n loadSql(),\n ]);\n const initialize = opts?.initialize ?? true;\n if (!initialize && !nodeFs().existsSync(resolved)) {\n throw new Error(`[wod] no database at ${resolved} — run \\`wod init\\` to create and initialize it`);\n }\n if (initialize) nodeFs().mkdirSync(nodePath().dirname(resolved), { recursive: true });\n const db = sql.libsqlDatabase(createClient({ url: `file:${resolved}` }));\n try {\n if (initialize) {\n await sql.initializeStore(db);\n await sql.initializeDomain(db);\n } else {\n // Guards only — no schema creation on an existing file either.\n await sql.verifyReadiness(db).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`${message} — run \\`wod init\\` to initialize it`, { cause: error });\n });\n }\n return { db, storage: new sql.SqlStorage(db), path: resolved, close: () => db.close() };\n } catch (error) {\n await db.close();\n throw error;\n }\n}\n\n/** Open a postgres/turso/remote-sqlite backend through the extracted server\n * adapter (dynamic on purpose: node-only subpath kept out of browser\n * bundles and external in the CLI bundle). Never falls back locally. */\nasync function openRemoteDb(\n env: Record<string, string | undefined>,\n label: string,\n opts?: { initialize?: boolean; create?: boolean },\n): Promise<CliDb> {\n const [{ openDatabase }, sql] = await Promise.all([\n import(/* @vite-ignore */ '@bitcobblers/wod-wiki-storage/sql/node') as Promise<{\n openDatabase: (env?: Record<string, string | undefined>, opts?: { create?: boolean }) => Promise<Database>;\n }>,\n loadSql(),\n ]);\n let db: Database | undefined;\n try {\n db = await openDatabase(env, { create: opts?.create });\n if (opts?.initialize === false) {\n await sql.verifyReadiness(db);\n } else {\n await sql.initializeStore(db);\n await sql.initializeDomain(db);\n }\n } catch (error) {\n await db?.close().catch(() => {});\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n `[wod] ${label}: ${message}${opts?.initialize === false ? ' — run `wod init` to initialize it' : ''}`,\n { cause: error },\n );\n }\n return { db, storage: new sql.SqlStorage(db), path: label, close: () => db.close() };\n}\n\n// ---------------------------------------------------------------------------\n// Identity helpers\n// ---------------------------------------------------------------------------\n\n/** RFC-4122 byte munging + formatting over a 16-byte digest slice. */\nexport function formatV5Digest(digest: Uint8Array): string {\n const bytes = digest.slice(0, 16);\n bytes[6] = (bytes[6] & 0x0f) | 0x50; // version 5\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // RFC-4122 variant\n const hex = [...bytes].map((b) => b.toString(16).padStart(2, '0'));\n return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10, 16).join('')}`;\n}\n\n/** RFC-4122 v5 (SHA-1) name-based UUID — deterministic seed/note identity. */\nexport function uuid5(namespace: string, name: string): string {\n return formatV5Digest(nodeCrypto().createHash('sha1').update(namespace).update(name).digest());\n}\n\n/** Local namespace for wod-CLI derived identities (not shared with seed ids). */\nexport const CLI_UUID_NAMESPACE = 'c0ffee00-8b1a-4e2c-9d3f-5a6b7c8d9e0f';\n\n/**\n * Stable note identity for a parsed/run source: the same file always maps\n * to the same note, so re-parsing updates instead of duplicating. Stdin\n * sources content-address (no stable path exists).\n */\nexport function stableNoteId(sourceLabel: string, content: string): string {\n if (sourceLabel && sourceLabel !== '-') {\n return uuid5(CLI_UUID_NAMESPACE, `wod-cli:${nodePath().resolve(process.cwd(), sourceLabel)}`);\n }\n return uuid5(CLI_UUID_NAMESPACE, `wod-cli:stdin:${content.length}:${content.slice(0, 256)}`);\n}\n\nexport function randomId(): string {\n return nodeCrypto().randomUUID();\n}\n\n// ---------------------------------------------------------------------------\n// WQL store adapters over the sqlite rows\n// ---------------------------------------------------------------------------\n\nasync function allRows(sql: SqlApi, db: Database, store: string): Promise<unknown[]> {\n return sql.listRows(db, sql.storeDefinition(store));\n}\n\nasync function rowsByIndex(sql: SqlApi, db: Database, store: string, index: string, only: string): Promise<unknown[]> {\n return sql.listRows(db, sql.storeDefinition(store), { only }, undefined, index);\n}\n\n/** EventStore over the `events` table — whole-table reads, keyed writes. */\nexport function sqliteEventStore(db: Database): EventStore {\n const all = async (): Promise<EventRecord[]> => (await allRows(await loadSql(), db, 'events')) as EventRecord[];\n return {\n getEventsByTimeRange: async (start, end) => (await all()).filter((r) => r.timestamp >= start && r.timestamp <= end),\n getEventsByResult: async (resultId) => (await all()).filter((r) => r.resultId === resultId),\n getEventsForNote: async (noteId) => (await all()).filter((r) => r.noteId === noteId),\n getEventsByContent: async (blockContentId) => (await all()).filter((r) => r.blockContentId === blockContentId),\n scanAll: all,\n appendEvents: async (appended) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n for (const row of appended) await sql.putRow(tx, eventsDef, row);\n });\n },\n finalizeSummaries: async (resultId, finals) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n const existing = ((await sql.listRows(tx, eventsDef)) as EventRecord[]).filter(\n (r) => r.resultId === resultId && r.grain === 'summary' && r.origin !== 'user',\n );\n for (const row of existing) await sql.deleteRows(tx, eventsDef, row.id);\n for (const row of finals) await sql.putRow(tx, eventsDef, row);\n });\n },\n deleteEvents: async (ids) => {\n const sql = await loadSql();\n await db.transaction(async (tx) => {\n const eventsDef = sql.storeDefinition('events');\n for (const id of ids) await sql.deleteRows(tx, eventsDef, id);\n });\n },\n };\n}\n\ninterface StoredTag { id: string; label: string; type?: string }\ninterface StoredNoteTag { id: string; noteId: string; tagId: string }\n\n/** NoteQueryStore over the notes/tags/note_tags rows + domain projection reads. */\nexport function sqliteNoteStore(db: Database): NoteQueryStore {\n return {\n getAllNotes: async () => (await allRows(await loadSql(), db, 'notes')) as never,\n getNotesByIds: async (noteIds) => {\n const sql = await loadSql();\n const rows = await sql.getRows(db, sql.storeDefinition('notes'), [...noteIds]) as Array<Note | undefined>;\n return rows.filter((row): row is Note => row !== undefined);\n },\n getNoteIdsForTag: async (label) => {\n const sql = await loadSql();\n const tags = ((await allRows(sql, db, 'tags')) as StoredTag[]).filter((t) => t.label === label);\n const ids: Record<string, true> = {};\n for (const tag of tags) {\n for (const row of await rowsByIndex(sql, db, 'note_tags', 'by-tag', tag.id)) {\n ids[(row as StoredNoteTag).noteId] = true;\n }\n }\n return new Set(Object.keys(ids));\n },\n getNoteTagLabels: async (noteId) => {\n const sql = await loadSql();\n const tagRows = (await allRows(sql, db, 'tags')) as StoredTag[];\n const labelById: Record<string, string> = {};\n for (const t of tagRows) labelById[t.id] = t.label;\n const links = (await rowsByIndex(sql, db, 'note_tags', 'by-note', noteId)) as StoredNoteTag[];\n return links.map((l) => labelById[l.tagId]).filter((l): l is string => typeof l === 'string');\n },\n queryDomain: async (request) => {\n // WQL's domain wire is a structural mirror of the storage DomainQuery.\n const result = await (await loadSql()).handleDomainQuery(db, request as never);\n return result as WqlDomainReadResult;\n },\n };\n}\n\n/** BlockQueryStore over the block_index rows + domain projection reads. */\nexport function sqliteBlockStore(db: Database): BlockQueryStore {\n return {\n getAllBlocks: async () => (await allRows(await loadSql(), db, 'block_index')) as never,\n queryDomain: async (request) => {\n const result = await (await loadSql()).handleDomainQuery(db, { ...request, plan: 'blocks' } as never);\n return result as WqlDomainReadResult;\n },\n };\n}\n\ninterface Slugged { slug: string }\n\n/**\n * EffortQueryStore: rows the seed wrote into the `efforts` registry win by\n * slug; the lang-bundled registry fills the rest (same fallback the\n * playground's RegistryEffortStore performs).\n */\nexport function sqliteEffortStore(db: Database): EffortQueryStore {\n return {\n getAllEfforts: async () => {\n const stored = (await allRows(await loadSql(), db, 'efforts')) as Slugged[];\n const bySlug: Record<string, unknown> = {};\n for (const effort of stored) bySlug[effort.slug] = effort;\n for (const effort of bundledEfforts as unknown as Slugged[]) {\n bySlug[effort.slug] ??= effort;\n }\n return Object.values(bySlug) as never;\n },\n };\n}\n\n/** Generic by-index reader over a store table — the QueryService seam shape. */\nexport interface IndexStore { getAllFromIndex(index: string, key: string): Promise<unknown[]> }\n\n/** Indexed reads over `block_efforts` / `tags` / `note_tags` rows. */\nexport function sqliteIndexStore(db: Database, store: 'block_efforts' | 'tags' | 'note_tags'): IndexStore {\n return {\n getAllFromIndex: async (index, key) => rowsByIndex(await loadSql(), db, store, index, key),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Download bundles (exchange feedstock)\n// ---------------------------------------------------------------------------\n\nexport interface NoteBundle {\n note: Note | undefined;\n}\n\nexport interface SessionBundle {\n session: Session;\n events: EventRecord[];\n}\n\n/** Fetch the whole authored Note. */\nexport async function getNoteBundle(db: Database, noteId: string): Promise<NoteBundle> {\n const sql = await loadSql();\n const note = await sql.getRow(db, sql.storeDefinition('notes'), noteId) as Note | undefined;\n return { note };\n}\n\n/** Fetch a session + its event/summary rows. */\nexport async function getSessionBundle(db: Database, resultId: string): Promise<SessionBundle | undefined> {\n const sql = await loadSql();\n const session = await sql.getRow(db, sql.storeDefinition('sessions'), resultId) as Session | undefined;\n if (!session) return undefined;\n const events = await sql.listRows(db, sql.storeDefinition('events'), { only: resultId }, undefined, 'by-result-grain') as EventRecord[];\n return { session, events };\n}\n\n/** Fetch one effort registry row by slug. */\nexport async function getEffortBySlug(db: Database, slug: string): Promise<Record<string, unknown> | undefined> {\n const sql = await loadSql();\n const efforts = (await allRows(sql, db, 'efforts')) as Array<{ slug: string } & Record<string, unknown>>;\n return efforts.find((e) => e.slug === slug);\n}\n\n/** Fetch tag rows of one type (e.g. 'equipment'). */\nexport async function listTagsByType(db: Database, type: string): Promise<Array<{ id: string; label: string; type?: string }>> {\n const sql = await loadSql();\n const tags = (await allRows(sql, db, 'tags')) as Array<{ id: string; label: string; type?: string }>;\n return tags.filter((t) => t.type === type);\n}\n"]}
|