@bitcobblers/wod-wiki-storage 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/{chunk-Y576CUFQ.mjs → chunk-7ZCBM5NS.mjs} +3 -3
- package/dist/chunk-7ZCBM5NS.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/sql/index.cjs +318 -7
- package/dist/sql/index.cjs.map +1 -1
- package/dist/sql/index.d.cts +158 -3
- package/dist/sql/index.d.ts +158 -3
- package/dist/sql/index.mjs +310 -9
- package/dist/sql/index.mjs.map +1 -1
- package/dist/{wire-Cfvz-I0h.d.cts → wire-CiFcjo6_.d.cts} +1 -1
- package/dist/{wire-Cfvz-I0h.d.ts → wire-CiFcjo6_.d.ts} +1 -1
- package/package.json +6 -6
- package/dist/chunk-Y576CUFQ.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { validateNoteBlocks } from '@bitcobblers/wod-wiki-core';
|
|
2
2
|
|
|
3
3
|
// src/schema.ts
|
|
4
|
-
var DB_VERSION =
|
|
4
|
+
var DB_VERSION = 30;
|
|
5
5
|
var COLUMN_TYPES = {
|
|
6
6
|
notes: { date: "number", createdAt: "number" },
|
|
7
7
|
page: { createdAt: "number" },
|
|
@@ -483,5 +483,5 @@ function bufferToOps(storeNames, buffer, cleared) {
|
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
export { COLUMN_TYPES, DB_VERSION, DEFAULT_MEMBERSHIP_ID, DOMAIN_PROJECTION_VERSION, STORE_DEFS, StorageError, USER_OWNED_STORES, bufferSlot, bufferToOps, bufferedGet, compareKeys, createDefaultMembership, encodeKey, extractKeyPart, isDirty, isRange, keyFromValue, keyInRange, overlayRows, parseDomainQueryResult, rangeFromIDB, rowsEqual, stampUserOwned, validateNoteWrite, validateSessionWrite, validateStorageRow, validateStoredPins };
|
|
486
|
-
//# sourceMappingURL=chunk-
|
|
487
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-7ZCBM5NS.mjs.map
|
|
487
|
+
//# sourceMappingURL=chunk-7ZCBM5NS.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/membership.ts","../src/wire.ts","../src/domain.ts","../src/sql/errors.ts","../src/validation.ts","../src/overlay.ts"],"names":["a","b","validateNoteBlocks"],"mappings":"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","file":"chunk-7ZCBM5NS.mjs","sourcesContent":["/** Fresh schema shared by browser, SQL and in-memory adapters. */\n\nimport type { StoreName } from './contract';\n\n// DOMAIN_PROJECTION_VERSION lives in ./domain (re-exported by the package\n// index) — deliberately not re-exported here to avoid a star-export\n// ambiguity between ./schema and ./domain.\n\n// V30 adds the browser-local sync journal stores (sync_outbox/sync_state in\n// IndexedDBStorage) to the versioned browser schema. SQL/API StoreDefs are\n// UNCHANGED — the sync tables are layered separately (_wodwiki_sync_*) — so\n// SQL databases at v29 pass the StoreDef equality guard and migrate forward\n// without touching rows (see sql/store.ts initializeStore).\nexport const DB_VERSION = 30;\n\n/**\n * Typed field metadata — column type per extracted field path, shared with\n * the API so its SQL DDL derives DOUBLE PRECISION / INTEGER / BOOLEAN /\n * TEXT from this table instead of a hardcoded per-index allowlist.\n *\n * Extraction rule (API side): a primary-key column `k<i>` takes the type of\n * STORE_DEFS store's keyPath[i]; an index column `i_<index>_<part>` takes the\n * type of that index's keyPath[part] here. Anything absent defaults to TEXT.\n * Civil-date strings stay TEXT on purpose (page.date is 'YYYY-MM-DD');\n * instants are epoch-ms numbers (notes.date, createdAt, timestamp).\n */\nexport type StorageColumnType = 'number' | 'text' | 'boolean';\n\nexport const COLUMN_TYPES: Record<StoreName, Record<string, StorageColumnType>> = {\n notes: { date: 'number', createdAt: 'number' },\n page: { createdAt: 'number' }, // page.date is a civil 'YYYY-MM-DD' string → TEXT\n page_notes: { position: 'number', createdAt: 'number' },\n tags: { createdAt: 'number' },\n tag_types: { createdAt: 'number' },\n note_tags: {},\n block_revisions: { version: 'number', savedAt: 'number' },\n sessions: {\n blockVersion: 'number',\n startTime: 'number',\n endTime: 'number',\n duration: 'number',\n roundsCompleted: 'number',\n totalRounds: 'number',\n repsCompleted: 'number',\n completed: 'boolean',\n createdAt: 'number',\n },\n attachments: { createdAt: 'number' },\n events: {\n timestamp: 'number',\n blockVersion: 'number',\n line: 'number',\n sourceStatementId: 'number',\n stackLevel: 'number',\n 'timeSpan.started': 'number',\n 'timeSpan.ended': 'number',\n },\n field_catalog: {},\n field_sources: {},\n field_values: {},\n field_catalog_meta: {},\n efforts: { 'baseAttributes.met': 'number' },\n block_index: {\n blockVersion: 'number',\n sourceRevision: 'number',\n from: 'number',\n to: 'number',\n position: 'number',\n createdAt: 'number',\n isStatic: 'boolean',\n },\n block_efforts: { createdAt: 'number', isStatic: 'boolean' },\n meta: {},\n memberships: { createdAt: 'number' },\n};\n\nexport interface IndexDef {\n name: string;\n keyPath: string[];\n unique?: boolean;\n multiEntry?: boolean;\n}\n\nexport interface StoreDef {\n name: StoreName;\n keyPath: string[];\n indexes: IndexDef[];\n /** System stores survive wipe() (identity must not be reset with data). */\n system?: boolean;\n}\n\nexport const STORE_DEFS: StoreDef[] = [\n // 1. notes\n { name: 'notes', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'] },\n { name: 'by-created', keyPath: ['createdAt'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2. page\n { name: 'page', keyPath: ['id'], indexes: [\n { name: 'by-date', keyPath: ['date'], unique: true },\n { name: 'by-slug', keyPath: ['slug'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 2b. page_notes (V22)\n { name: 'page_notes', keyPath: ['id'], indexes: [\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-page-note', keyPath: ['pageId', 'noteId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3. tags\n { name: 'tags', keyPath: ['id'], indexes: [\n { name: 'by-label', keyPath: ['label'], unique: true },\n { name: 'by-type', keyPath: ['type'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 3a. tag_types (V23)\n { name: 'tag_types', keyPath: ['id'], indexes: [\n { name: 'by-name', keyPath: ['name'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 4. note_tags\n { name: 'note_tags', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-tag', keyPath: ['tagId'] },\n { name: 'by-note-tag', keyPath: ['noteId', 'tagId'], unique: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n { name: 'block_revisions', keyPath: ['noteId', 'blockId', 'version'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-block', keyPath: ['noteId', 'blockId'] },\n ] },\n // 6. sessions\n { name: 'sessions', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-completed', keyPath: ['createdAt'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-block', keyPath: ['blockId'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-origin', keyPath: ['origin'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 8. attachments\n { name: 'attachments', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-time', keyPath: ['createdAt'] },\n { name: 'by-page', keyPath: ['pageId'] },\n { name: 'by-result', keyPath: ['resultId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 9. events\n { name: 'events', keyPath: ['id'], indexes: [\n { name: 'by-timestamp', keyPath: ['timestamp'] },\n { name: 'by-result-grain', keyPath: ['resultId', 'grain'] },\n { name: 'by-content-grain', keyPath: ['blockContentId', 'grain'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-outputType', keyPath: ['outputType'] },\n { name: 'by-grain', keyPath: ['grain'] },\n { name: 'by-metric-date', keyPath: ['metricDateKeys'], multiEntry: true },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 10. field catalog\n { name: 'field_catalog', keyPath: ['id'], indexes: [\n { name: 'by-path', keyPath: ['path'] },\n ] },\n { name: 'field_sources', keyPath: ['id'], indexes: [] },\n { name: 'field_values', keyPath: ['key'], indexes: [\n { name: 'by-field', keyPath: ['fieldId'] },\n ] },\n { name: 'field_catalog_meta', keyPath: ['id'], indexes: [] },\n // 11. efforts\n { name: 'efforts', keyPath: ['slug'], indexes: [\n { name: 'by-discipline', keyPath: ['baseAttributes.discipline'] },\n { name: 'by-source', keyPath: ['registrySource'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 12. block_index\n { name: 'block_index', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-content', keyPath: ['blockContentId'] },\n { name: 'by-type', keyPath: ['dataType'] },\n { name: 'by-source', keyPath: ['sourceId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 13. block_efforts\n { name: 'block_efforts', keyPath: ['id'], indexes: [\n { name: 'by-note', keyPath: ['noteId'] },\n { name: 'by-effort', keyPath: ['effortSlug'] },\n { name: 'by-block', keyPath: ['blockContentId'] },\n { name: 'by-user', keyPath: ['userId'] },\n ] },\n // 14. meta\n { name: 'meta', keyPath: ['key'], indexes: [] },\n // 15. memberships (V25, system — survives wipe; truth lives in\n // localStorage locally, in the SQL table on the API)\n { name: 'memberships', keyPath: ['id'], indexes: [], system: true },\n];\n","/**\n * membership.ts — identity contract shared by both backends.\n *\n * The single local membership (id 'default') is the owner of every\n * user-created record: adapters stamp `userId` onto rows on write (see\n * stampUserOwned), and the by-user index in STORE_DEFS is the ownership\n * crosswalk per store. Seed rows (seedOrigin === 'seed') stay unowned —\n * they are bundled content, not user data.\n */\n\nimport type { StoreName } from './contract';\nimport type { Membership } from './entities';\n\nexport const DEFAULT_MEMBERSHIP_ID = 'default';\n\nexport function createDefaultMembership(now: number = Date.now()): Membership {\n return { id: DEFAULT_MEMBERSHIP_ID, displayName: 'Anonymous', createdAt: now };\n}\n\n/** Stores that can hold user-created rows. Excluded: the pure seed catalog\n * (field_*), meta, and memberships itself. The by-user index in STORE_DEFS\n * mirrors this list — keep in lockstep. */\nexport const USER_OWNED_STORES: readonly StoreName[] = [\n 'notes', 'page', 'page_notes', 'tags', 'tag_types', 'note_tags',\n 'sessions', 'attachments', 'events',\n 'efforts', 'block_index', 'block_efforts',\n];\n\nconst STAMPABLE: Record<string, true> = Object.fromEntries(\n USER_OWNED_STORES.map((s) => [s, true as const])\n);\n\n/** Stamps `userId` onto a user-owned row. Seed rows pass through untouched;\n * already-stamped rows are returned as-is (no churn on re-put). Values in\n * non-user-owned stores are returned unchanged. */\nexport function stampUserOwned(store: StoreName, value: unknown, userId: string): unknown {\n if (!STAMPABLE[store]) return value;\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value;\n const row = value as Record<string, unknown>;\n if (row.seedOrigin === 'seed') return value;\n if (row.userId === userId) return value;\n return { ...row, userId };\n}\n","/**\n * Wire DTOs + key helpers shared by the storage client (ApiStorage) and the\n * API server. Keys are scalars or scalar tuples (keyPath order); ranges bound\n * them. Over HTTP, keys/ranges travel as urlencoded JSON query params.\n *\n * Range-typed helpers accept real IDBKeyRange instances AND plain RangeDTO\n * literals — non-IDB runtimes (Bun, node, tests) have no IDBKeyRange global,\n * so everything duck-types on field shape.\n */\n\nimport type { StoreName } from './contract';\nimport type { StoreDef } from './schema';\n\nexport type Scalar = string | number;\n\n/** Primary key: scalar for single-property keyPaths, tuple for compound. */\nexport type KeyDTO = Scalar | Scalar[];\n\nexport interface RangeDTO {\n only?: KeyDTO;\n /** Inclusive lower bound unless lowerOpen. Scalar or tuple (keyPath order). */\n lower?: KeyDTO;\n /** Inclusive upper bound unless upperOpen. Scalar or tuple (keyPath order). */\n upper?: KeyDTO;\n lowerOpen?: boolean;\n upperOpen?: boolean;\n}\n\nexport type TxOp =\n | { op: 'check'; store: StoreName; key: KeyDTO; value: unknown | null }\n | { op: 'put'; store: StoreName; value: unknown }\n | { op: 'delete'; store: StoreName; key: KeyDTO }\n | { op: 'clear'; store: StoreName };\n\n/** Anything shaped like a range: real IDBKeyRange or a plain RangeDTO literal. */\nexport function isRange(arg: unknown): arg is RangeDTO {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) &&\n ('only' in arg || 'lower' in arg || 'upper' in arg || 'lowerOpen' in arg || 'upperOpen' in arg);\n}\n\n/** Reads one dotted property path ('a.b.c') off a row. */\nexport function extractKeyPart(value: unknown, dottedPath: string): Scalar | undefined {\n let cur: unknown = value;\n for (const part of dottedPath.split('.')) {\n if (cur === null || typeof cur !== 'object') return undefined;\n // Dynamic key on an untyped row: index-signature view is the only way to read it.\n const row = cur as Record<string, unknown>;\n if (!(part in row)) return undefined;\n cur = row[part];\n }\n if (cur === null || typeof cur === 'object' || cur === undefined) return undefined;\n return cur as Scalar; // string/number/boolean leaf narrowed to the wire subset\n}\n\n/** Extracts a row's primary key per the store's inline keyPath. */\nexport function keyFromValue(def: StoreDef, value: unknown): KeyDTO {\n const parts = def.keyPath.map((p) => extractKeyPart(value, p));\n for (const [i, part] of parts.entries()) {\n if (part === undefined) {\n throw new Error(`keyFromValue(${def.name}): keyPath part '${def.keyPath[i]}' missing on value`);\n }\n }\n // Loop above proved every element defined.\n const key = parts as Scalar[];\n return key.length === 1 ? key[0] : key;\n}\n\n/** Canonical url-safe string form of a key (also the buffer/tx match key). */\nexport function encodeKey(key: KeyDTO): string {\n return encodeURIComponent(JSON.stringify(key));\n}\n\n/**\n * Converts an IndexedDB query — bare key, IDBKeyRange, or an already-wire\n * RangeDTO — to its wire form. Duck-types: objects with lower/upper/\n * lowerOpen/upperOpen fields (real ranges or plain literals) pass through;\n * scalars and tuple arrays become {only}.\n */\nexport function rangeFromIDB(query?: IDBValidKey | IDBKeyRange | RangeDTO): RangeDTO | undefined {\n if (query === undefined) return undefined;\n if (!isRange(query)) {\n // Bare IDBValidKey (scalar/tuple; exotic keys like Date pass through lossy).\n const key = query as KeyDTO;\n return { only: key };\n }\n if (query.only !== undefined) return query;\n const wire: RangeDTO = {};\n if (query.lower !== undefined && query.lower !== null) {\n wire.lower = query.lower;\n wire.lowerOpen = query.lowerOpen === true;\n }\n if (query.upper !== undefined && query.upper !== null) {\n // IDB upper bound idiom [prefix, []] uses [] > strings; normalize [] to \\uffff on wire.\n wire.upper = Array.isArray(query.upper)\n ? (query.upper.map((p) => (Array.isArray(p) && p.length === 0 ? '\\uffff' : p)) as KeyDTO)\n : query.upper;\n wire.upperOpen = query.upperOpen === true;\n }\n return wire.lower !== undefined || wire.upper !== undefined ? wire : undefined;\n}\n\n/** IndexedDB key ordering: numbers < strings < tuples; tuples lexicographic. */\nexport function compareKeys(a: KeyDTO, b: KeyDTO): number {\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return Array.isArray(a) ? 1 : -1;\n for (let i = 0; i < Math.min(a.length, b.length); i++) {\n const c = compareKeys(a[i], b[i]);\n if (c !== 0) return c;\n }\n return a.length - b.length;\n }\n if (typeof a === 'number' && typeof b === 'number') {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n if (typeof a === 'number' || typeof b === 'number') return typeof a === 'number' ? -1 : 1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** True when a key matches a wire range (IDB bound semantics). */\nexport function keyInRange(key: KeyDTO, range: RangeDTO): boolean {\n if (range.only !== undefined) return compareKeys(key, range.only) === 0;\n if (range.lower !== undefined) {\n const c = compareKeys(key, range.lower);\n if (c < 0 || (c === 0 && range.lowerOpen === true)) return false;\n }\n if (range.upper !== undefined) {\n const c = compareKeys(key, range.upper);\n if (c > 0 || (c === 0 && range.upperOpen === true)) return false;\n }\n return true;\n}\n","import type { BlockIndexRow, Note, Page, PageNote, Tag } from './entities';\nimport { validateNoteBlocks } from '@bitcobblers/wod-wiki-core';\n\nexport const DOMAIN_PROJECTION_VERSION = 2;\n\nexport type DomainPredicate =\n | { field: 'id' | 'noteId' | 'type' | 'catalog' | 'source' | 'tags' | 'effort'; values: string[]; negate?: boolean }\n | { field: 'text'; value: string }\n | { field: 'date'; start: number; end: number; endExclusive?: boolean }\n | { field: 'page'; value: boolean }\n | { field: 'defaultNotes'; feeds: boolean }\n | { field: 'sourceFence' };\n\nexport type DomainOrder = {\n field: 'id' | 'createdAt' | 'date' | 'title' | 'noteTitle' | 'dataType' | 'position';\n direction: 'asc' | 'desc';\n};\n\nexport type DomainQuery = {\n plan: 'notes' | 'blocks' | 'entries';\n selection?: DomainPredicate[];\n filters?: DomainPredicate[];\n order?: DomainOrder[];\n offset?: number;\n limit?: number;\n};\n\nexport interface DomainEntry {\n note: Note;\n tags: Tag[];\n links: PageNote[];\n pages: Page[];\n}\n\nexport type DomainQueryResult = {\n projectionVersion: typeof DOMAIN_PROJECTION_VERSION;\n selectedCount: number;\n matchedCount: number;\n} & (\n | { plan: 'notes'; rows: Note[] }\n | { plan: 'blocks'; rows: BlockIndexRow[] }\n | { plan: 'entries'; rows: DomainEntry[] }\n);\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction optionalStrings(row: Record<string, unknown>, fields: string[]): boolean {\n return fields.every(field => row[field] === undefined || typeof row[field] === 'string');\n}\n\nfunction finiteNumbers(row: Record<string, unknown>, fields: string[]): boolean {\n return fields.every(field => typeof row[field] === 'number' && Number.isFinite(row[field]));\n}\n\nfunction isNote(value: unknown): value is Note {\n if (!isObject(value) || typeof value.id !== 'string' || typeof value.title !== 'string'\n || typeof value.rawContent !== 'string' || !Number.isSafeInteger(value.sourceRevision)\n || typeof value.sourceRevision !== 'number' || value.sourceRevision < 1 || !isObject(value.blocks)\n || !finiteNumbers(value, ['createdAt'])\n || (value.date !== undefined && !finiteNumbers(value, ['date']))\n || !optionalStrings(value, ['type', 'sourceId', 'catalog', 'sourcePath', 'seedOrigin', 'seedChunkId'])\n || (value.tags !== undefined && (!Array.isArray(value.tags) || !value.tags.every(tag => typeof tag === 'string')))) return false;\n try {\n validateNoteBlocks(value.rawContent, value.blocks as Note['blocks'], value.sourceRevision);\n return true;\n } catch { return false; }\n}\n\nfunction isBlock(value: unknown): value is BlockIndexRow {\n return isObject(value) && typeof value.id === 'string' && typeof value.noteId === 'string'\n && typeof value.blockId === 'string' && finiteNumbers(value, ['blockVersion', 'sourceRevision', 'from', 'to', 'createdAt'])\n && value.id === `${value.noteId}:${value.blockId}`\n && typeof value.blockVersion === 'number' && Number.isSafeInteger(value.blockVersion) && value.blockVersion > 0\n && typeof value.sourceRevision === 'number' && Number.isSafeInteger(value.sourceRevision) && value.sourceRevision > 0\n && typeof value.from === 'number' && Number.isSafeInteger(value.from) && value.from >= 0\n && typeof value.to === 'number' && Number.isSafeInteger(value.to) && value.to > value.from\n && ['wod', 'query', 'widget', 'embed'].includes(String(value.dataType)) && typeof value.rawContent === 'string'\n && typeof value.noteTitle === 'string'\n && optionalStrings(value, ['blockContentId', 'sourceId', 'sourcePath', 'routeId'])\n && (value.position === undefined || finiteNumbers(value, ['position']))\n && (value.isStatic === undefined || typeof value.isStatic === 'boolean');\n}\n\n\nfunction isTag(value: unknown): value is Tag {\n return isObject(value) && typeof value.id === 'string' && typeof value.label === 'string'\n && finiteNumbers(value, ['createdAt']) && optionalStrings(value, ['type']);\n}\n\nfunction isPage(value: unknown): value is Page {\n return isObject(value) && typeof value.id === 'string' && finiteNumbers(value, ['createdAt'])\n && optionalStrings(value, ['date', 'slug', 'title']);\n}\n\nfunction isLink(value: unknown): value is PageNote {\n return isObject(value) && typeof value.id === 'string' && typeof value.noteId === 'string'\n && typeof value.pageId === 'string' && finiteNumbers(value, ['createdAt'])\n && (value.position === undefined || finiteNumbers(value, ['position']));\n}\n\nfunction isEntry(value: unknown): value is DomainEntry {\n return isObject(value) && isNote(value.note)\n && Array.isArray(value.tags) && value.tags.every(isTag)\n && Array.isArray(value.links) && value.links.every(isLink)\n && Array.isArray(value.pages) && value.pages.every(isPage);\n}\n\nexport function parseDomainQueryResult(value: unknown, plan: DomainQuery['plan']): DomainQueryResult {\n if (!isObject(value) || value.projectionVersion !== DOMAIN_PROJECTION_VERSION\n || value.plan !== plan || !Array.isArray(value.rows)\n || typeof value.selectedCount !== 'number' || !Number.isSafeInteger(value.selectedCount) || value.selectedCount < 0\n || typeof value.matchedCount !== 'number' || !Number.isSafeInteger(value.matchedCount) || value.matchedCount < 0\n || value.matchedCount > value.selectedCount || value.rows.length > value.matchedCount) {\n throw new Error('ApiStorage: invalid or stale domain projection response');\n }\n const counts = { projectionVersion: DOMAIN_PROJECTION_VERSION, selectedCount: value.selectedCount, matchedCount: value.matchedCount } as const;\n switch (plan) {\n case 'notes':\n if (value.rows.every(isNote)) return { ...counts, plan, rows: value.rows };\n break;\n case 'blocks':\n if (value.rows.every(isBlock)) return { ...counts, plan, rows: value.rows };\n break;\n case 'entries':\n if (value.rows.every(isEntry)) return { ...counts, plan, rows: value.rows };\n break;\n }\n throw new Error('ApiStorage: invalid domain query rows');\n}\n","/**\n * StorageError — the single error type every shared SQL layer throws.\n * Replaces the API server's HTTP-specific error: `status` keeps the wire\n * mapping for the HTTP surface, `code` carries a stable machine identifier\n * (e.g. 'domain_projection_unavailable') for browser callers.\n */\nexport class StorageError extends Error {\n constructor(readonly status: number, message: string, readonly code?: string) {\n super(message);\n this.name = 'StorageError';\n }\n}\n","import { validateNoteBlocks, type BlockRevision, type Note, type Session } from '@bitcobblers/wod-wiki-core';\nimport type { StoreName } from './contract';\nimport { StorageError } from './sql/errors';\n\nexport function rowsEqual(left: unknown, right: unknown): boolean {\n if (Object.is(left, right)) return true;\n if (left instanceof ArrayBuffer && right instanceof ArrayBuffer) {\n const a = new Uint8Array(left), b = new Uint8Array(right);\n return a.length === b.length && a.every((value, i) => value === b[i]);\n }\n if (typeof left !== 'object' || left === null || typeof right !== 'object' || right === null) return false;\n if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right)\n && left.length === right.length && left.every((value, i) => rowsEqual(value, right[i]));\n const a = Object.keys(left).filter(key => Reflect.get(left, key) !== undefined);\n const b = Object.keys(right).filter(key => Reflect.get(right, key) !== undefined);\n return a.length === b.length && a.every(key => Object.hasOwn(right, key)\n && rowsEqual(Reflect.get(left, key), Reflect.get(right, key)));\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new StorageError(400, 'storage row must be an object');\n return value as Record<string, unknown>;\n}\n\nexport function validateStorageRow(store: StoreName, value: unknown): void {\n if (store !== 'notes' && store !== 'block_revisions' && store !== 'sessions' && store !== 'block_index') return;\n const row = record(value);\n const positive = (field: string): boolean => typeof row[field] === 'number' && Number.isSafeInteger(row[field]) && row[field] > 0;\n const required = (field: string): boolean => typeof row[field] === 'string' && row[field].length > 0;\n if (store === 'notes') {\n if (!required('id') || typeof row.title !== 'string' || typeof row.rawContent !== 'string'\n || !positive('sourceRevision') || typeof row.createdAt !== 'number' || !Number.isFinite(row.createdAt)\n || 'segments' in row || 'segmentIds' in row\n || (row.date !== undefined && (typeof row.date !== 'number' || !Number.isFinite(row.date)))\n || (row.seedOrigin !== undefined && row.seedOrigin !== 'seed' && row.seedOrigin !== 'user')\n || (row.seedVersion !== undefined && !positive('seedVersion'))\n || (row.tags !== undefined && (!Array.isArray(row.tags) || !row.tags.every(tag => typeof tag === 'string')))\n || ['type', 'sourceId', 'sourcePath', 'catalog', 'seedChunkId'].some(field => row[field] !== undefined && typeof row[field] !== 'string')) {\n throw new StorageError(400, 'invalid whole Note', 'invalid_note_blocks');\n }\n try { validateNoteBlocks(row.rawContent, record(row.blocks) as Note['blocks'], row.sourceRevision as number); }\n catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid block map', 'invalid_note_blocks'); }\n } else if (store === 'block_revisions') {\n if (!required('noteId') || !required('blockId') || !positive('version') || typeof row.rawContent !== 'string'\n || typeof row.savedAt !== 'number' || !Number.isFinite(row.savedAt)\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.kind))\n || (row.kind === 'wod' ? row.dialect !== 'time' && row.dialect !== 'log' : row.dialect !== undefined || row.sport !== undefined)\n || (row.sport !== undefined && typeof row.sport !== 'string')) throw new StorageError(400, 'invalid block revision', 'invalid_note_blocks');\n try {\n validateNoteBlocks(row.rawContent as string, { [String(row.blockId)]: {\n id: String(row.blockId), kind: row.kind as BlockRevision['kind'], version: row.version as number,\n sourceRevision: 1, from: 0, to: (row.rawContent as string).length,\n ...(row.dialect === undefined ? {} : { dialect: row.dialect as 'time' | 'log' }),\n ...(row.sport === undefined ? {} : { sport: row.sport as string }),\n } }, 1);\n } catch (error) { throw new StorageError(400, error instanceof Error ? error.message : 'invalid revision source', 'invalid_note_blocks'); }\n } else if (store === 'sessions') {\n if (!required('noteId') || !required('blockId') || !positive('blockVersion')\n || ['segmentId', 'segmentVersion', 'version', 'rawContent', 'script', 'serializedScript', 'source', 'data', 'logs'].some(field => field in row)) {\n throw new StorageError(400, 'Session requires immutable block pin', 'invalid_session_pin');\n }\n } else if (!required('noteId') || !required('blockId') || !positive('blockVersion') || !positive('sourceRevision')\n || row.id !== `${row.noteId}:${row.blockId}` || !Number.isSafeInteger(row.from) || !Number.isSafeInteger(row.to)\n || 'segmentId' in row || 'segmentVersion' in row\n || !['wod', 'query', 'widget', 'embed'].includes(String(row.dataType))\n || typeof row.rawContent !== 'string' || typeof row.noteTitle !== 'string'\n || typeof row.from !== 'number' || typeof row.to !== 'number' || row.from < 0 || row.to <= row.from) {\n throw new StorageError(400, 'invalid actionable block projection', 'invalid_note_blocks');\n }\n}\n\nexport function validateNoteWrite(previous: unknown, value: unknown): void {\n if (previous === undefined || rowsEqual(previous, value)) return;\n const before = record(previous), after = record(value);\n if (typeof before.sourceRevision !== 'number' || typeof after.sourceRevision !== 'number'\n || after.sourceRevision < before.sourceRevision\n || ((!rowsEqual(before.blocks, after.blocks) || before.rawContent !== after.rawContent)\n && after.sourceRevision <= before.sourceRevision)) throw new StorageError(409, 'stale Note source revision', 'transaction_conflict');\n}\n\nexport function validateSessionWrite(previous: unknown, value: unknown): void {\n if (previous === undefined) return;\n const before = record(previous), after = record(value);\n if (before.noteId !== after.noteId || before.blockId !== after.blockId || before.blockVersion !== after.blockVersion)\n throw new StorageError(409, 'Session pin is immutable', 'invalid_session_pin');\n}\n\nexport async function validateStoredPins(\n notes: Note[], sessions: Session[], getRevisions: (keys: IDBValidKey[]) => Promise<(BlockRevision | undefined)[]>,\n): Promise<void> {\n const keys: IDBValidKey[] = [];\n for (const note of notes) for (const block of Object.values(note.blocks)) keys.push([note.id, block.id, block.version]);\n for (const session of sessions) keys.push([session.noteId, session.blockId, session.blockVersion]);\n const revisions = await getRevisions(keys);\n let i = 0;\n for (const note of notes) for (const block of Object.values(note.blocks)) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== block.kind || revision.rawContent !== note.rawContent.slice(block.from, block.to)\n || revision.dialect !== block.dialect || revision.sport !== block.sport) throw new StorageError(409, 'Note block has no matching immutable revision', 'invalid_note_blocks');\n }\n for (let sessionIndex = 0; sessionIndex < sessions.length; sessionIndex++) {\n const revision = revisions[i++];\n if (!revision || revision.kind !== 'wod') throw new StorageError(409, 'Session pin must reference a saved workout revision', 'invalid_session_pin');\n }\n}\n","/**\n * Transaction write-buffer + read-overlay helpers shared by the HTTP\n * ApiStorage and the SQL SqlStorage backends. A transaction buffers puts and\n * deletes; reads overlay the buffer on backend rows in op order, so\n * read-your-writes holds without round-tripping uncommitted data.\n */\n\nimport type { StoreName } from './contract';\nimport {\n compareKeys,\n extractKeyPart,\n keyFromValue,\n keyInRange,\n type KeyDTO,\n type RangeDTO,\n type TxOp,\n} from './wire';\nimport type { StoreDef } from './schema';\n\nexport interface BufferedPut { kind: 'put'; value: unknown }\nexport interface BufferedDelete { kind: 'delete'; key: KeyDTO }\nexport type BufferEntry = BufferedPut | BufferedDelete;\n\n// Buffer slot key: store + \\u0000 + raw JSON of the key (JSON text never\n// contains a literal \\u0000, so the separator is unambiguous).\nexport const bufferSlot = (store: StoreName, key: KeyDTO): string => `${store}\\u0000${JSON.stringify(key)}`;\n\n/** True when this tx has buffered writes (puts, deletes or a clear) for the store. */\nexport function isDirty(store: StoreName, buffer?: Map<string, BufferEntry>, cleared?: Set<StoreName>): boolean {\n if (cleared?.has(store)) return true;\n if (!buffer) return false;\n const prefix = `${store}\\u0000`;\n for (const slot of buffer.keys()) {\n if (slot.startsWith(prefix)) return true;\n }\n return false;\n}\n\n/** Point lookup against the buffer; undefined means consult the backend. */\nexport function bufferedGet<T>(store: StoreName, key: KeyDTO, buffer?: Map<string, BufferEntry>):\n | { hit: true; value: T }\n | { hit: false }\n | undefined {\n if (!buffer) return undefined;\n const entry = buffer.get(bufferSlot(store, key));\n if (!entry) return undefined;\n return entry.kind === 'put' ? { hit: true, value: entry.value as T } : { hit: false };\n}\n\n/**\n * Applies buffered puts and deletes before range filtering, ordering and\n * paging. Rows missing an index field are not in the index (IDB semantics);\n * multi-entry keys match when any entry is in range.\n */\nexport function overlayRows<T>(\n def: StoreDef,\n store: StoreName,\n buffer: Map<string, BufferEntry> | undefined,\n cleared: Set<StoreName> | undefined,\n rows: T[],\n count?: number,\n range?: RangeDTO,\n indexName?: string,\n): T[] {\n if (!buffer || !isDirty(store, buffer, cleared)) return count !== undefined ? rows.slice(0, count) : rows;\n const out = new Map<string, T>();\n if (!cleared?.has(store)) {\n // Out-map keys are raw JSON key text — same form as buffer slot suffixes.\n for (const row of rows) out.set(JSON.stringify(keyFromValue(def, row)), row);\n }\n const prefix = `${store}\\u0000`;\n for (const [slot, entry] of buffer) {\n if (!slot.startsWith(prefix)) continue;\n if (entry.kind === 'put') out.set(slot.slice(prefix.length), entry.value as T);\n else out.delete(slot.slice(prefix.length));\n }\n // Dirty reads fetch the complete candidate range: buffered deletes can\n // remove the remote head, and puts can change index membership or order.\n const index = indexName ? def.indexes.find(i => i.name === indexName) : undefined;\n if (indexName && !index) throw new Error(`unknown index '${indexName}' for ${store}`);\n const keyOf = (row: T): KeyDTO | undefined => {\n if (!index) return keyFromValue(def, row);\n const parts = index.keyPath.map(path => extractKeyPart(row, path));\n if (parts.some(part => part === undefined)) return undefined;\n const keys = parts.filter((part): part is string | number => part !== undefined);\n return keys.length === 1 ? keys[0] : keys;\n };\n const matches = (row: T): boolean => {\n if (index?.multiEntry) {\n let values: unknown = row;\n for (const part of index.keyPath[0].split('.')) {\n if (values === null || typeof values !== 'object' || !(part in values)) return false;\n values = Reflect.get(values, part);\n }\n return Array.isArray(values) && values.some(value =>\n (typeof value === 'string' || typeof value === 'number') && (!range || keyInRange(value, range)));\n }\n const key = keyOf(row);\n return key !== undefined && (!range || keyInRange(key, range));\n };\n const merged = [...out.values()].filter(matches);\n merged.sort((a, b) => {\n const primary = compareKeys(keyFromValue(def, a), keyFromValue(def, b));\n if (index?.multiEntry) return primary;\n const ak = keyOf(a), bk = keyOf(b);\n return ak !== undefined && bk !== undefined ? compareKeys(ak, bk) || primary : primary;\n });\n return count !== undefined ? merged.slice(0, count) : merged;\n}\n\n/** Drains the tx buffer into wire ops (clears first, then puts/deletes in op order). */\nexport function bufferToOps(storeNames: Iterable<StoreName>, buffer: Map<string, BufferEntry>, cleared: Set<StoreName>): TxOp[] {\n const known = new Set(storeNames);\n const ops: TxOp[] = [];\n for (const store of cleared) {\n if (known.has(store)) ops.push({ op: 'clear', store });\n }\n for (const [slot, entry] of buffer) {\n const sep = slot.indexOf('\\u0000');\n const store = slot.slice(0, sep) as StoreName;\n if (!known.has(store)) continue;\n if (entry.kind === 'put') ops.push({ op: 'put', store, value: entry.value });\n else ops.push({ op: 'delete', store, key: JSON.parse(slot.slice(sep + 1)) as KeyDTO });\n }\n return ops;\n}\n"]}
|