@mostlyrightmd/core 1.1.2 → 1.2.0

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.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/dist/discovery/index.cjs +44 -7
  3. package/dist/discovery/index.cjs.map +1 -1
  4. package/dist/discovery/index.d.cts +34 -6
  5. package/dist/discovery/index.d.ts +34 -6
  6. package/dist/discovery/index.mjs +44 -7
  7. package/dist/discovery/index.mjs.map +1 -1
  8. package/dist/index.cjs +39 -1
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +16 -2
  11. package/dist/index.d.ts +16 -2
  12. package/dist/index.global.js +37 -1
  13. package/dist/index.global.js.map +1 -1
  14. package/dist/index.mjs +37 -1
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/internal/cache/index.browser.cjs +77 -4
  17. package/dist/internal/cache/index.browser.cjs.map +1 -1
  18. package/dist/internal/cache/index.browser.d.cts +8 -2
  19. package/dist/internal/cache/index.browser.d.ts +8 -2
  20. package/dist/internal/cache/index.browser.mjs +10 -5
  21. package/dist/internal/cache/index.browser.mjs.map +1 -1
  22. package/dist/internal/cache/index.cjs +79 -2
  23. package/dist/internal/cache/index.cjs.map +1 -1
  24. package/dist/internal/cache/index.d.cts +12 -6
  25. package/dist/internal/cache/index.d.ts +12 -6
  26. package/dist/internal/cache/index.mjs +12 -3
  27. package/dist/internal/cache/index.mjs.map +1 -1
  28. package/dist/internal/{chunk-PKJXHY27.mjs → chunk-IPC4XUYW.mjs} +70 -1
  29. package/dist/internal/chunk-IPC4XUYW.mjs.map +1 -0
  30. package/dist/internal/{keys-B7C8C88N.d.cts → versionedCacheStore-DyHDqFIC.d.cts} +23 -1
  31. package/dist/internal/{keys-B7C8C88N.d.ts → versionedCacheStore-DyHDqFIC.d.ts} +23 -1
  32. package/dist/preprocessing/index.cjs +150 -0
  33. package/dist/preprocessing/index.cjs.map +1 -0
  34. package/dist/preprocessing/index.d.cts +111 -0
  35. package/dist/preprocessing/index.d.ts +111 -0
  36. package/dist/preprocessing/index.mjs +121 -0
  37. package/dist/preprocessing/index.mjs.map +1 -0
  38. package/dist/temporal/index.cjs.map +1 -1
  39. package/dist/temporal/index.mjs.map +1 -1
  40. package/dist/validator.cjs.map +1 -1
  41. package/dist/validator.mjs.map +1 -1
  42. package/package.json +34 -2
  43. package/dist/internal/chunk-PKJXHY27.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import {
2
+ CACHE_SCHEMA_VERSION,
2
3
  DB_NAME,
3
4
  IndexedDBStore,
4
5
  MemoryStore,
@@ -10,18 +11,21 @@ import {
10
11
  isWritableYear,
11
12
  lockKeyFor,
12
13
  shouldSkipCacheForCurrentLstMonth,
13
- shouldSkipCacheForCurrentLstYear
14
- } from "../chunk-PKJXHY27.mjs";
14
+ shouldSkipCacheForCurrentLstYear,
15
+ versionedCacheStore
16
+ } from "../chunk-IPC4XUYW.mjs";
15
17
 
16
18
  // src/internal/cache/index.browser.ts
17
19
  async function defaultCacheStore() {
18
- if (typeof indexedDB !== "undefined") return new IndexedDBStore();
19
- return new MemoryStore();
20
+ const inner = typeof indexedDB !== "undefined" ? new IndexedDBStore() : new MemoryStore();
21
+ return versionedCacheStore(inner, CACHE_SCHEMA_VERSION);
20
22
  }
21
23
  export {
24
+ CACHE_SCHEMA_VERSION,
22
25
  DB_NAME as INDEXEDDB_DB_NAME,
23
26
  IndexedDBStore,
24
27
  MemoryStore,
28
+ CACHE_SCHEMA_VERSION as VERSIONED_CACHE_SCHEMA_VERSION,
25
29
  cacheKeyForClimate,
26
30
  cacheKeyForObservations,
27
31
  defaultCacheStore,
@@ -31,6 +35,7 @@ export {
31
35
  isWritableYear,
32
36
  lockKeyFor,
33
37
  shouldSkipCacheForCurrentLstMonth,
34
- shouldSkipCacheForCurrentLstYear
38
+ shouldSkipCacheForCurrentLstYear,
39
+ versionedCacheStore
35
40
  };
36
41
  //# sourceMappingURL=index.browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/internal/cache/index.browser.ts"],"sourcesContent":["// Browser/MV3 entry for @mostlyrightmd/core/internal/cache.\n//\n// Iter-8 H15: the iter-1/iter-2 fixes (dynamic `await import('./fs.js')`\n// behind a runtime feature-detect + dropping the FsStore re-export from\n// the barrel) eliminated STATIC references to FsStore from the cache\n// subbundle but NOT dynamic ones. esbuild, when bundling for browser/MV3\n// targets, still follows `await import(\"./fs.js\")` from `default.ts`\n// into the FsStore chunk and pulls `node:crypto`, `node:fs/promises`,\n// `node:os`, `node:path`, and `proper-lockfile` into the bundle —\n// breaking `pnpm size` for `packages-ts/meta/dist/index.mjs`.\n//\n// The architectural fix: package.json conditional exports route Node\n// consumers to `./index.ts` (this file's sibling — keeps FsStore via\n// dynamic import) and browser/MV3 consumers to THIS file. This file has\n// NO reference to `./fs.js` via ANY mechanism — static import, dynamic\n// import, or re-export. esbuild cannot follow what isn't there.\n//\n// Exports MUST mirror `index.ts` exactly, MINUS anything that references\n// FsStore. The runtime priority for `defaultCacheStore` here is:\n// 1. `typeof indexedDB !== \"undefined\"` → IndexedDBStore.\n// 2. else → MemoryStore.\n// (The FsStore branch is unreachable in browser/MV3 bundles by\n// construction — there's no `process.versions?.node` in a service\n// worker anyway, but more importantly the source code is absent so\n// esbuild's static analysis cannot drag the Node-only chunk in.)\n\nimport { IndexedDBStore } from \"./indexeddb.js\";\nimport { MemoryStore } from \"./memory.js\";\nimport type { CacheStore } from \"./types.js\";\n\nexport type { CacheStore, CacheSetOptions, CacheEntry } from \"./types.js\";\nexport { lockKeyFor } from \"./types.js\";\nexport { MemoryStore } from \"./memory.js\";\nexport { IndexedDBStore, DB_NAME as INDEXEDDB_DB_NAME } from \"./indexeddb.js\";\nexport type { IndexedDBStoreOptions } from \"./indexeddb.js\";\nexport {\n shouldSkipCacheForCurrentLstMonth,\n shouldSkipCacheForCurrentLstYear,\n isLiveSource,\n isWithinVolatileWindow,\n isWritableMonth,\n isWritableYear,\n} from \"./skip-rules.js\";\nexport { cacheKeyForObservations, cacheKeyForClimate } from \"./keys.js\";\n\n/**\n * Browser/MV3 variant of {@link defaultCacheStore}. Auto-detects the best\n * available CacheStore in a browser/edge environment:\n *\n * 1. IndexedDB present → {@link IndexedDBStore}\n * 2. else → {@link MemoryStore}\n *\n * Returns a NEW instance per call.\n *\n * Iter-8 H15: kept async so the signature matches the Node entry's\n * `defaultCacheStore` (which awaits a dynamic import). Callers that\n * `await defaultCacheStore()` work unchanged when the package.json\n * conditional exports flip them between entries.\n */\nexport async function defaultCacheStore(): Promise<CacheStore> {\n if (typeof indexedDB !== \"undefined\") return new IndexedDBStore();\n return new MemoryStore();\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA2DA,eAAsB,oBAAyC;AAC7D,MAAI,OAAO,cAAc,YAAa,QAAO,IAAI,eAAe;AAChE,SAAO,IAAI,YAAY;AACzB;","names":[]}
1
+ {"version":3,"sources":["../../../src/internal/cache/index.browser.ts"],"sourcesContent":["// Browser/MV3 entry for @mostlyrightmd/core/internal/cache.\n//\n// Iter-8 H15: the iter-1/iter-2 fixes (dynamic `await import('./fs.js')`\n// behind a runtime feature-detect + dropping the FsStore re-export from\n// the barrel) eliminated STATIC references to FsStore from the cache\n// subbundle but NOT dynamic ones. esbuild, when bundling for browser/MV3\n// targets, still follows `await import(\"./fs.js\")` from `default.ts`\n// into the FsStore chunk and pulls `node:crypto`, `node:fs/promises`,\n// `node:os`, `node:path`, and `proper-lockfile` into the bundle —\n// breaking `pnpm size` for `packages-ts/meta/dist/index.mjs`.\n//\n// The architectural fix: package.json conditional exports route Node\n// consumers to `./index.ts` (this file's sibling — keeps FsStore via\n// dynamic import) and browser/MV3 consumers to THIS file. This file has\n// NO reference to `./fs.js` via ANY mechanism — static import, dynamic\n// import, or re-export. esbuild cannot follow what isn't there.\n//\n// Exports MUST mirror `index.ts` exactly, MINUS anything that references\n// FsStore. The runtime priority for `defaultCacheStore` here is:\n// 1. `typeof indexedDB !== \"undefined\"` → IndexedDBStore.\n// 2. else → MemoryStore.\n// (The FsStore branch is unreachable in browser/MV3 bundles by\n// construction — there's no `process.versions?.node` in a service\n// worker anyway, but more importantly the source code is absent so\n// esbuild's static analysis cannot drag the Node-only chunk in.)\n\nimport { IndexedDBStore } from \"./indexeddb.js\";\nimport { MemoryStore } from \"./memory.js\";\nimport { CACHE_SCHEMA_VERSION, type CacheStore } from \"./types.js\";\nimport { versionedCacheStore } from \"./versionedCacheStore.js\";\n\nexport type { CacheStore, CacheSetOptions, CacheEntry } from \"./types.js\";\nexport { lockKeyFor } from \"./types.js\";\nexport { MemoryStore } from \"./memory.js\";\nexport { IndexedDBStore, DB_NAME as INDEXEDDB_DB_NAME } from \"./indexeddb.js\";\nexport type { IndexedDBStoreOptions } from \"./indexeddb.js\";\nexport {\n shouldSkipCacheForCurrentLstMonth,\n shouldSkipCacheForCurrentLstYear,\n isLiveSource,\n isWithinVolatileWindow,\n isWritableMonth,\n isWritableYear,\n} from \"./skip-rules.js\";\nexport { cacheKeyForObservations, cacheKeyForClimate } from \"./keys.js\";\n// Phase 21 21-03 fix-iter-2 (ts-architect CRITICAL): browser entry must\n// also re-export the version adapter + canonical version constant so\n// downstream code that imports them via this path resolves to the same\n// symbols as the Node entry.\nexport {\n versionedCacheStore,\n CACHE_SCHEMA_VERSION as VERSIONED_CACHE_SCHEMA_VERSION,\n} from \"./versionedCacheStore.js\";\nexport { CACHE_SCHEMA_VERSION } from \"./types.js\";\n\n/**\n * Browser/MV3 variant of {@link defaultCacheStore}. Auto-detects the best\n * available CacheStore in a browser/edge environment:\n *\n * 1. IndexedDB present → {@link IndexedDBStore}\n * 2. else → {@link MemoryStore}\n *\n * Phase 21 21-03 fix-iter-2 (ts-architect CRITICAL): the concrete store\n * is wrapped in `versionedCacheStore(CACHE_SCHEMA_VERSION)` so pre-\n * Phase-18 entries silently miss. The Node entry already does this; the\n * browser entry was missed in iter-1 — browser/MV3 consumers were still\n * served stale cache rows. Fix is symmetric.\n *\n * Returns a NEW instance per call.\n *\n * Iter-8 H15: kept async so the signature matches the Node entry's\n * `defaultCacheStore` (which awaits a dynamic import). Callers that\n * `await defaultCacheStore()` work unchanged when the package.json\n * conditional exports flip them between entries.\n */\nexport async function defaultCacheStore(): Promise<CacheStore> {\n const inner = typeof indexedDB !== \"undefined\" ? new IndexedDBStore() : new MemoryStore();\n return versionedCacheStore(inner, CACHE_SCHEMA_VERSION);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2EA,eAAsB,oBAAyC;AAC7D,QAAM,QAAQ,OAAO,cAAc,cAAc,IAAI,eAAe,IAAI,IAAI,YAAY;AACxF,SAAO,oBAAoB,OAAO,oBAAoB;AACxD;","names":[]}
@@ -223,9 +223,11 @@ var init_fs = __esm({
223
223
  // src/internal/cache/index.ts
224
224
  var cache_exports = {};
225
225
  __export(cache_exports, {
226
+ CACHE_SCHEMA_VERSION: () => CACHE_SCHEMA_VERSION,
226
227
  INDEXEDDB_DB_NAME: () => DB_NAME,
227
228
  IndexedDBStore: () => IndexedDBStore,
228
229
  MemoryStore: () => MemoryStore,
230
+ VERSIONED_CACHE_SCHEMA_VERSION: () => CACHE_SCHEMA_VERSION,
229
231
  cacheKeyForClimate: () => cacheKeyForClimate,
230
232
  cacheKeyForObservations: () => cacheKeyForObservations,
231
233
  defaultCacheStore: () => defaultCacheStore,
@@ -235,7 +237,8 @@ __export(cache_exports, {
235
237
  isWritableYear: () => isWritableYear,
236
238
  lockKeyFor: () => lockKeyFor,
237
239
  shouldSkipCacheForCurrentLstMonth: () => shouldSkipCacheForCurrentLstMonth,
238
- shouldSkipCacheForCurrentLstYear: () => shouldSkipCacheForCurrentLstYear
240
+ shouldSkipCacheForCurrentLstYear: () => shouldSkipCacheForCurrentLstYear,
241
+ versionedCacheStore: () => versionedCacheStore
239
242
  });
240
243
  module.exports = __toCommonJS(cache_exports);
241
244
 
@@ -243,6 +246,7 @@ module.exports = __toCommonJS(cache_exports);
243
246
  function lockKeyFor(key) {
244
247
  return `mostlyright:cache:lock:${key}`;
245
248
  }
249
+ var CACHE_SCHEMA_VERSION = "v2-phase18-integer-f";
246
250
 
247
251
  // src/internal/cache/memory.ts
248
252
  var MemoryStore = class {
@@ -395,8 +399,78 @@ var IndexedDBStore = class {
395
399
  }
396
400
  };
397
401
 
402
+ // src/internal/cache/versionedCacheStore.ts
403
+ var VERSION_FIELD = "_cache_schema_version";
404
+ function isVersionedEntry(v) {
405
+ if (v === null || typeof v !== "object") return false;
406
+ if (!(VERSION_FIELD in v)) return false;
407
+ return typeof v[VERSION_FIELD] === "string";
408
+ }
409
+ function hasListKeys(s) {
410
+ return typeof s.listKeys === "function";
411
+ }
412
+ var VersionedCacheStore = class {
413
+ #inner;
414
+ #version;
415
+ constructor(inner, version) {
416
+ if (typeof version !== "string" || version.length === 0) {
417
+ throw new TypeError("versionedCacheStore: version must be a non-empty string");
418
+ }
419
+ this.#inner = inner;
420
+ this.#version = version;
421
+ }
422
+ /**
423
+ * Test/diagnostics seam: return the underlying store so tests can assert
424
+ * which concrete backend `defaultCacheStore()` selected. NOT a production
425
+ * API — production code MUST use the wrapped store so version
426
+ * invalidation fires on stale reads.
427
+ *
428
+ * @internal
429
+ */
430
+ __peekInner() {
431
+ return this.#inner;
432
+ }
433
+ async get(key) {
434
+ const raw = await this.#inner.get(key);
435
+ if (raw === null) return null;
436
+ if (!isVersionedEntry(raw)) {
437
+ return null;
438
+ }
439
+ if (raw._cache_schema_version !== this.#version) {
440
+ return null;
441
+ }
442
+ return raw.value;
443
+ }
444
+ async set(key, value, opts) {
445
+ const wrapped = {
446
+ value,
447
+ [VERSION_FIELD]: this.#version
448
+ };
449
+ await this.#inner.set(key, wrapped, opts);
450
+ }
451
+ async delete(key) {
452
+ await this.#inner.delete(key);
453
+ }
454
+ async withLock(key, fn) {
455
+ return this.#inner.withLock(key, fn);
456
+ }
457
+ async listKeys(prefix) {
458
+ if (hasListKeys(this.#inner)) {
459
+ return this.#inner.listKeys(prefix);
460
+ }
461
+ return Object.freeze([]);
462
+ }
463
+ };
464
+ function versionedCacheStore(inner, version) {
465
+ return new VersionedCacheStore(inner, version);
466
+ }
467
+
398
468
  // src/internal/cache/default.ts
399
469
  async function defaultCacheStore() {
470
+ const inner = await pickConcreteStore();
471
+ return versionedCacheStore(inner, CACHE_SCHEMA_VERSION);
472
+ }
473
+ async function pickConcreteStore() {
400
474
  if (typeof indexedDB !== "undefined") return new IndexedDBStore();
401
475
  if (typeof process !== "undefined" && typeof process.versions === "object" && process.versions !== null && typeof process.versions.node === "string") {
402
476
  const { FsStore: FsStore2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
@@ -1372,9 +1446,11 @@ function cacheKeyForClimate(station, year) {
1372
1446
  }
1373
1447
  // Annotate the CommonJS export names for ESM import in node:
1374
1448
  0 && (module.exports = {
1449
+ CACHE_SCHEMA_VERSION,
1375
1450
  INDEXEDDB_DB_NAME,
1376
1451
  IndexedDBStore,
1377
1452
  MemoryStore,
1453
+ VERSIONED_CACHE_SCHEMA_VERSION,
1378
1454
  cacheKeyForClimate,
1379
1455
  cacheKeyForObservations,
1380
1456
  defaultCacheStore,
@@ -1384,6 +1460,7 @@ function cacheKeyForClimate(station, year) {
1384
1460
  isWritableYear,
1385
1461
  lockKeyFor,
1386
1462
  shouldSkipCacheForCurrentLstMonth,
1387
- shouldSkipCacheForCurrentLstYear
1463
+ shouldSkipCacheForCurrentLstYear,
1464
+ versionedCacheStore
1388
1465
  });
1389
1466
  //# sourceMappingURL=index.cjs.map