@memberjunction/core 6.1.0-edge.0 → 6.1.0-edge.2

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 (77) hide show
  1. package/dist/generic/InMemoryLocalStorageProvider.d.ts +6 -0
  2. package/dist/generic/InMemoryLocalStorageProvider.d.ts.map +1 -1
  3. package/dist/generic/InMemoryLocalStorageProvider.js +6 -0
  4. package/dist/generic/InMemoryLocalStorageProvider.js.map +1 -1
  5. package/dist/generic/baseEngineRegistry.d.ts +14 -0
  6. package/dist/generic/baseEngineRegistry.d.ts.map +1 -1
  7. package/dist/generic/baseEngineRegistry.js +32 -0
  8. package/dist/generic/baseEngineRegistry.js.map +1 -1
  9. package/dist/generic/baseEntity.d.ts +366 -29
  10. package/dist/generic/baseEntity.d.ts.map +1 -1
  11. package/dist/generic/baseEntity.js +872 -96
  12. package/dist/generic/baseEntity.js.map +1 -1
  13. package/dist/generic/dataHooks.d.ts +5 -0
  14. package/dist/generic/dataHooks.d.ts.map +1 -1
  15. package/dist/generic/dataHooks.js +27 -3
  16. package/dist/generic/dataHooks.js.map +1 -1
  17. package/dist/generic/databaseProviderBase.d.ts +44 -17
  18. package/dist/generic/databaseProviderBase.d.ts.map +1 -1
  19. package/dist/generic/databaseProviderBase.js +96 -52
  20. package/dist/generic/databaseProviderBase.js.map +1 -1
  21. package/dist/generic/entityCompanion.d.ts +218 -0
  22. package/dist/generic/entityCompanion.d.ts.map +1 -0
  23. package/dist/generic/entityCompanion.js +170 -0
  24. package/dist/generic/entityCompanion.js.map +1 -0
  25. package/dist/generic/entityInfo.d.ts +21 -0
  26. package/dist/generic/entityInfo.d.ts.map +1 -1
  27. package/dist/generic/entityInfo.js +21 -0
  28. package/dist/generic/entityInfo.js.map +1 -1
  29. package/dist/generic/entitySavePlan.d.ts +199 -0
  30. package/dist/generic/entitySavePlan.d.ts.map +1 -0
  31. package/dist/generic/entitySavePlan.js +213 -0
  32. package/dist/generic/entitySavePlan.js.map +1 -0
  33. package/dist/generic/entityTransactionScope.d.ts +125 -0
  34. package/dist/generic/entityTransactionScope.d.ts.map +1 -0
  35. package/dist/generic/entityTransactionScope.js +115 -0
  36. package/dist/generic/entityTransactionScope.js.map +1 -0
  37. package/dist/generic/interfaces.d.ts +122 -35
  38. package/dist/generic/interfaces.d.ts.map +1 -1
  39. package/dist/generic/interfaces.js +27 -0
  40. package/dist/generic/interfaces.js.map +1 -1
  41. package/dist/generic/localCacheManager.d.ts +123 -5
  42. package/dist/generic/localCacheManager.d.ts.map +1 -1
  43. package/dist/generic/localCacheManager.js +254 -9
  44. package/dist/generic/localCacheManager.js.map +1 -1
  45. package/dist/generic/providerBase.d.ts +112 -0
  46. package/dist/generic/providerBase.d.ts.map +1 -1
  47. package/dist/generic/providerBase.js +303 -9
  48. package/dist/generic/providerBase.js.map +1 -1
  49. package/dist/generic/relatedRecordBatchLoader.d.ts +39 -0
  50. package/dist/generic/relatedRecordBatchLoader.d.ts.map +1 -0
  51. package/dist/generic/relatedRecordBatchLoader.js +154 -0
  52. package/dist/generic/relatedRecordBatchLoader.js.map +1 -0
  53. package/dist/generic/relatedRecordCollection.d.ts +588 -0
  54. package/dist/generic/relatedRecordCollection.d.ts.map +1 -0
  55. package/dist/generic/relatedRecordCollection.js +1020 -0
  56. package/dist/generic/relatedRecordCollection.js.map +1 -0
  57. package/dist/generic/saveEntityGraphOperation.d.ts +148 -0
  58. package/dist/generic/saveEntityGraphOperation.d.ts.map +1 -0
  59. package/dist/generic/saveEntityGraphOperation.js +157 -0
  60. package/dist/generic/saveEntityGraphOperation.js.map +1 -0
  61. package/dist/generic/telemetryManager.d.ts +21 -1
  62. package/dist/generic/telemetryManager.d.ts.map +1 -1
  63. package/dist/generic/telemetryManager.js +21 -6
  64. package/dist/generic/telemetryManager.js.map +1 -1
  65. package/dist/index.d.ts +6 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +6 -3
  68. package/dist/index.js.map +1 -1
  69. package/dist/views/runView.d.ts +66 -0
  70. package/dist/views/runView.d.ts.map +1 -1
  71. package/dist/views/runView.js.map +1 -1
  72. package/package.json +3 -3
  73. package/readme.md +195 -1
  74. package/dist/generic/runReport.d.ts +0 -25
  75. package/dist/generic/runReport.d.ts.map +0 -1
  76. package/dist/generic/runReport.js +0 -38
  77. package/dist/generic/runReport.js.map +0 -1
@@ -64,7 +64,18 @@ export interface CacheStats {
64
64
  * to prevent data inconsistency.
65
65
  */
66
66
  export interface CachedRunViewData {
67
- /** The cached result rows */
67
+ /**
68
+ * The cached result rows.
69
+ *
70
+ * ⚠️ These rows are SHARED: under a reference-sharing storage provider (see
71
+ * `ILocalStorageProvider.SharesReferences`) they are the same objects held by every reader
72
+ * of this slot, and they are deep-frozen at write time. Mutating one corrupts process-wide
73
+ * state and throws a `TypeError`. Build a new array / new rows instead.
74
+ *
75
+ * Deliberately typed mutable rather than `readonly`: the runtime freeze is the enforcement,
76
+ * and a `readonly` marker here would be a compile break for existing downstream code that
77
+ * reads cache entries — without adding protection the freeze does not already provide.
78
+ */
68
79
  results: unknown[];
69
80
  /** The maximum __mj_UpdatedAt timestamp from the results */
70
81
  maxUpdatedAt: string;
@@ -79,13 +90,24 @@ export interface CachedRunViewData {
79
90
  * Backward-compatible: entries without this field are served normally (no regression).
80
91
  */
81
92
  schemaHash?: string;
93
+ /**
94
+ * Set when the slot was written with {@link CacheWriteOptions.ProviderInternalScaffolding}.
95
+ * Persisted so that in-place slot maintenance (`storeCachedResults`, driven by BaseEntity
96
+ * save/delete events) can carry the exemption FORWARD. Without it, the first save event
97
+ * touching a scaffolding slot would freeze it and break the owner that mutates those rows.
98
+ */
99
+ providerInternalScaffolding?: boolean;
82
100
  }
83
101
  /**
84
102
  * Return type for GetRunViewResult and ApplyDifferentialUpdate.
85
103
  * Includes rowCount (derived from results.length) and totalRowCount (from the database).
86
104
  */
87
105
  export interface CachedRunViewResult {
88
- /** The cached result rows */
106
+ /**
107
+ * The cached result rows — shared and deep-frozen; see {@link CachedRunViewData.results}.
108
+ * Callers that need to transform rows (e.g. GraphQL transport field renaming) must map
109
+ * onto copies: `results.map(r => ({ ...r }))`.
110
+ */
89
111
  results: unknown[];
90
112
  /** The maximum __mj_UpdatedAt timestamp from the results */
91
113
  maxUpdatedAt: string;
@@ -102,6 +124,36 @@ export interface CachedRunViewResult {
102
124
  * permanently disabling post-migration drift detection for that slot.
103
125
  */
104
126
  schemaHash?: string;
127
+ /**
128
+ * Surfaced from the stored payload so in-place maintenance can carry the freeze exemption
129
+ * forward. See {@link CachedRunViewData.providerInternalScaffolding}.
130
+ */
131
+ providerInternalScaffolding?: boolean;
132
+ }
133
+ /**
134
+ * Per-write options for the cache write methods.
135
+ */
136
+ export interface CacheWriteOptions {
137
+ /**
138
+ * Declares that this slot is **provider-internal scaffolding**: the provider doing the
139
+ * write is its only consumer, and the rows are transient input to that provider's own
140
+ * assembly step rather than data served to arbitrary callers.
141
+ *
142
+ * Such slots are exempt from the defensive deep-freeze. The freeze exists to stop
143
+ * *consumers* from corrupting shared rows they were handed; it buys nothing for rows with
144
+ * a single owner, and it would break owners that legitimately use those rows as scratch
145
+ * space.
146
+ *
147
+ * The motivating case is metadata bootstrap: `GetDatasetByName` caches each dataset item
148
+ * through this cache, and `PostProcessEntityMetadata` then hydrates a graph by sorting the
149
+ * row array in place and attaching child collections onto each entity/field row. Freezing
150
+ * those rows makes `GetAllMetadata()` throw and the process boots with no metadata at all.
151
+ *
152
+ * **Do not set this to avoid fixing a mutation.** If the rows reach anything other than
153
+ * the writing provider, the correct fix is for the mutator to copy first. Defaults to
154
+ * `false` — caller-facing results are always frozen.
155
+ */
156
+ ProviderInternalScaffolding?: boolean;
105
157
  }
106
158
  /**
107
159
  * Configuration for the LocalCacheManager
@@ -248,6 +300,12 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
248
300
  */
249
301
  static get Instance(): LocalCacheManager;
250
302
  private _storageProvider;
303
+ /**
304
+ * Whether the active storage provider hands back live object references, resolved once at
305
+ * initialization — from the provider's declared {@link ILocalStorageProvider.SharesReferences}
306
+ * when it states one, otherwise measured empirically. Gates the defensive deep-freeze.
307
+ */
308
+ private _sharesReferences;
251
309
  private _registry;
252
310
  private _initialized;
253
311
  private _initializePromise;
@@ -280,6 +338,23 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
280
338
  * @returns A promise that resolves when initialization is complete
281
339
  */
282
340
  Initialize(storageProvider: ILocalStorageProvider, config?: Partial<LocalCacheManagerConfig>): Promise<void>;
341
+ /**
342
+ * Decides whether the storage provider hands back live object references — the condition
343
+ * that makes the defensive deep-freeze necessary.
344
+ *
345
+ * Prefers the provider's declared {@link ILocalStorageProvider.SharesReferences}. When a
346
+ * provider does not state one (any implementation written before that property existed),
347
+ * MEASURE it rather than guessing: store a sentinel object, read it back, and compare
348
+ * identity. A reference-sharing store returns the very same object; anything with a
349
+ * serialization or structured-clone boundary returns a copy. This is what keeps the
350
+ * property optional — an external provider that never declares it still gets the correct
351
+ * protection instead of silently losing it to a falsy default.
352
+ *
353
+ * Fails closed to `false` if the probe cannot complete (a provider whose backing store is
354
+ * not ready at init): that matches the pre-freeze behavior rather than immobilizing rows
355
+ * for a provider we could not classify.
356
+ */
357
+ private resolveSharesReferences;
283
358
  /**
284
359
  * Internal initialization logic - only called once by the first caller
285
360
  */
@@ -609,7 +684,8 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
609
684
  *
610
685
  * @param name - The dataset name
611
686
  * @param itemFilters - Optional filters applied to the dataset
612
- * @param dataset - The dataset result to cache
687
+ * @param dataset - The dataset result to cache. Deep-frozen on reference-sharing storage,
688
+ * like every other cache write funnel — see below.
613
689
  * @param keyPrefix - Prefix for the cache key (typically includes connection info)
614
690
  */
615
691
  SetDataset(name: string, itemFilters: DatasetItemFilterType[] | undefined, dataset: DatasetResultType, keyPrefix: string): Promise<void>;
@@ -669,7 +745,7 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
669
745
  * pre-RLS format so normal cache sharing is preserved and no existing entries are invalidated.
670
746
  * @returns A unique, human-readable fingerprint string
671
747
  */
672
- GenerateRunViewFingerprint(params: RunViewParams, connectionPrefix?: string, rlsWhereClause?: string): string;
748
+ GenerateRunViewFingerprint(params: RunViewParams, connectionPrefix?: string, rlsWhereClause?: string, datasetSegment?: string): string;
673
749
  /**
674
750
  * Generates a hash string representing the aggregate expressions.
675
751
  * This ensures different aggregate configurations get different fingerprints.
@@ -711,6 +787,41 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
711
787
  * @returns The schema hash string, or undefined if the entity can't be resolved
712
788
  */
713
789
  ComputeSchemaHash(provider: IMetadataProvider | undefined, entityName: string): string | undefined;
790
+ /**
791
+ * Deep-freezes an about-to-be-stored cache payload when — and only when — the active
792
+ * storage provider hands out live object references
793
+ * ({@link ILocalStorageProvider.SharesReferences}).
794
+ *
795
+ * This is the cache's structural defense against consumer corruption. Under a
796
+ * reference-sharing provider the rows a caller receives ARE the cached rows, in both
797
+ * directions: on a hit the reader gets the stored array, and on a miss the cache stored
798
+ * the caller's own array. Any in-place mutation therefore edits process-wide state. One
799
+ * such mutation shipped as a P1 (a resolver renamed `__mj_CreatedAt` to its GraphQL
800
+ * transport alias in place, so every later read served rows `BaseEntity.SetMany`
801
+ * rejects). Freezing makes that failure immediate and attributable — a `TypeError` at
802
+ * the offending line — instead of silent corruption, and costs nothing per cache hit.
803
+ *
804
+ * On serializing providers this is a no-op: their stored data is already isolated, and
805
+ * freezing would only immobilize the caller's own rows for no safety gain.
806
+ *
807
+ * @param payload - The envelope being handed to the storage provider. Frozen in place;
808
+ * the same reference is returned for call-site convenience.
809
+ */
810
+ /**
811
+ * Whether the CURRENTLY-INSTALLED provider hands back live references.
812
+ *
813
+ * Prefers the active provider's own declaration, read live on each call — a property read,
814
+ * so it costs nothing on the write path, and it stays correct no matter how many times the
815
+ * provider is swapped or which code path does the swapping. `_sharesReferences` (resolved at
816
+ * `Initialize`/`SetStorageProvider`) is the fallback for providers that declare nothing, where
817
+ * the answer can only come from the async probe and therefore cannot be recomputed here.
818
+ *
819
+ * Belt-and-braces with the re-resolution in {@link SetStorageProvider}: that keeps the probed
820
+ * value correct across swaps, and this keeps DECLARED providers correct even if some future
821
+ * swap site forgets to re-resolve.
822
+ */
823
+ private activeProviderSharesReferences;
824
+ private freezeRowDataIfProviderSharesReferences;
714
825
  /**
715
826
  * Stores a RunView result in the cache.
716
827
  *
@@ -727,8 +838,11 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
727
838
  * AllowCaching gating in multi-provider scenarios (parallel client connections to multiple
728
839
  * servers). Falls back to `Metadata.Provider` (global default) when omitted, which is fine
729
840
  * for single-provider apps but wrong when AllowCaching differs across servers.
841
+ * @param ttlMs - Optional time-based expiry (required for external-data-source entities).
842
+ * @param options - See {@link CacheWriteOptions}. Pass `{ ProviderInternalScaffolding: true }`
843
+ * only for slots the writing provider is the sole consumer of.
730
844
  */
731
- SetRunViewResult(fingerprint: string, params: RunViewParams, results: unknown[], maxUpdatedAt: string, aggregateResults?: AggregateResult[], totalRowCount?: number, provider?: IMetadataProvider, ttlMs?: number): Promise<void>;
845
+ SetRunViewResult(fingerprint: string, params: RunViewParams, results: unknown[], maxUpdatedAt: string, aggregateResults?: AggregateResult[], totalRowCount?: number, provider?: IMetadataProvider, ttlMs?: number, options?: CacheWriteOptions): Promise<void>;
732
846
  /**
733
847
  * Retrieves a cached RunView result.
734
848
  *
@@ -887,6 +1001,10 @@ export declare class LocalCacheManager extends BaseSingleton<LocalCacheManager>
887
1001
  * @returns The cached results, maxUpdatedAt, rowCount, and queryId, or null if not found
888
1002
  */
889
1003
  GetRunQueryResult(fingerprint: string): Promise<{
1004
+ /**
1005
+ * The cached result rows — shared and deep-frozen under a reference-sharing storage
1006
+ * provider, exactly like {@link CachedRunViewData.results}. Do not mutate.
1007
+ */
890
1008
  results: unknown[];
891
1009
  maxUpdatedAt: string;
892
1010
  rowCount: number;
@@ -1 +1 @@
1
- {"version":3,"file":"localCacheManager.d.ts","sourceRoot":"","sources":["../../src/generic/localCacheManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyB,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACnI,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtE,OAAO,EAAc,eAAe,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAgB,MAAM,gBAAgB,CAAC;AAW5D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,sBAAsB;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAC9B,6BAA6B;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,6BAA6B;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACpC,iCAAiC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IACvC;;;;OAIG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;;;;OASG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CAC3B;AAqBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,MAAM,EAAE,KAAK,GAAG,SAAS,GAAG,kBAAkB,CAAC;IAE/C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD;;;GAGG;AACH,eAAO,MAAM,aAAa;IACtB,gCAAgC;;IAEhC,iCAAiC;;IAEjC,gCAAgC;;IAEhC,yBAAyB;;IAEzB,8CAA8C;;CAExC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC;AAM7E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,iBAAkB,SAAQ,aAAa,CAAC,iBAAiB,CAAC;IACnE;;OAEG;IACH,WAAkB,QAAQ,IAAI,iBAAiB,CAE9C;IAED,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAAkD;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB,CAAoC;IAE7D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2B;IAExD;;;;OAIG;IACH,OAAO,CAAC,uBAAuB,CAAuC;IAEtE,SAAS;IAQT;;;;;;;;;;OAUG;IACI,UAAU,CACb,eAAe,EAAE,qBAAqB,EACtC,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC;IAiBhB;;OAEG;YACW,YAAY;IAoB1B;;OAEG;IACH,IAAW,aAAa,IAAI,OAAO,CAElC;IAED;;OAEG;IACH,IAAW,MAAM,IAAI,uBAAuB,CAE3C;IAED;;OAEG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,IAAI;IAInE;;;;;;OAMG;IACI,yBAAyB,CAAC,UAAU,EAAE;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IAIhF;;;;;;;;;OASG;IACU,kBAAkB,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqClF;;;;;;;;;OASG;IACH,SAAS,CAAC,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK1E;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAS7D;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IAM9C;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IAMjD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IAMjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IA6BvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAa3D;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IAoB/B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;;OAGG;IACI,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAIxE;;;;;;OAMG;YACW,4BAA4B;IA0B1C;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IA2BnC;;;;;;;OAOG;cACa,qBAAqB,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4DlF;;;;;OAKG;cACa,2BAA2B,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqHxF;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAWjC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAKhC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAO;IAE5C;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;IASnB,iHAAiH;IACjH,OAAO,CAAC,wBAAwB;IAUhC;;;OAGG;YACW,gCAAgC;IAyC9C;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAmE;IAE3F;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACI,sBAAsB,CACzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC7C,MAAM,IAAI;IAiBb;;;;;;;;;;;;;OAaG;IACI,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAgC1D;;;OAGG;IACH,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IAMD;;;;;;;OAOG;IACU,UAAU,CACnB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAChD,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAiChB;;;;;;;OAOG;IACU,UAAU,CACnB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAChD,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAsBpC;;;;;;;OAOG;IACU,mBAAmB,CAC5B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAChD,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAevB;;;;;;OAMG;IACU,YAAY,CACrB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAChD,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAchB;;;;;;;OAOG;IACU,eAAe,CACxB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAChD,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,0BAA0B,CAAC,MAAM,EAAE,aAAa,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IAgGpH;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;;;;;;;;;;;;;OAeG;IACI,gCAAgC,CACnC,aAAa,EAAE,eAAe,EAAE,GAAG,SAAS,EAC5C,mBAAmB,EAAE,mBAAmB,EAAE,GAAG,SAAS,GACvD,eAAe,EAAE,GAAG,SAAS;IAyBhC;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAUlB;;;;;;;OAOG;IACI,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAczG;;;;;;;;;;;;;;;;OAgBG;IACU,gBAAgB,CACzB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,OAAO,EAAE,EAClB,YAAY,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,eAAe,EAAE,EACpC,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAiIhB;;;;;;;OAOG;IACU,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAcvF;;;;;;;;;;;;;;;;;;;;OAoBG;IACU,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAyBxG;;;;;;;;OAQG;IACH,OAAO,CAAC,8BAA8B;IA0CtC;;;;OAIG;IACU,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxE;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACU,uBAAuB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,OAAO,EAAE,EACtB,gBAAgB,EAAE,MAAM,EAAE,EAC1B,mBAAmB,EAAE,MAAM,EAC3B,eAAe,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM,EACvB,gBAAgB,CAAC,EAAE,eAAe,EAAE,EACpC,QAAQ,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAqHtC;;;;;;;;;;OAUG;YACW,mBAAmB;IAmBjC;;;;;;OAMG;IACU,kBAAkB,CAC3B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,GAAG,EAAE,YAAY,EACjB,eAAe,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC;IAuCnB;;;;;;;;OAQG;IACU,kBAAkB,CAC3B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,YAAY,EACjB,eAAe,EAAE,MAAM,GACxB,OAAO,CAAC,OAAO,CAAC;IAuCnB;;;;;;;;;;;;;OAaG;YACW,kBAAkB;IAkDhC;;;;;OAKG;IACU,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BtE;;;;;;;;;;;OAWG;IACI,2BAA2B,CAC9B,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,gBAAgB,CAAC,EAAE,MAAM,EACzB,YAAY,CAAC,EAAE,MAAM,GACtB,MAAM;IAwBT;;;;;;;;;;OAUG;IACU,iBAAiB,CAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAAE,EAClB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC;IAgDhB;;;;;OAKG;IACU,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QACzD,OAAO,EAAE,OAAO,EAAE,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,uFAAuF;QACvF,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;IA+CT;;;;OAIG;IACU,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWzE;;;;;OAKG;IACU,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBpE;;;;;;OAMG;IACU,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAC9D,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI,CAAC;IAcT;;OAEG;IACI,aAAa,IAAI,cAAc,EAAE;IAIxC;;;;OAIG;IACI,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,EAAE;IAI/D;;OAEG;IACI,QAAQ,IAAI,UAAU;IAyB7B;;OAEG;IACI,UAAU,IAAI,MAAM;IAS3B;;;;;OAKG;IACU,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB/D;;;;OAIG;IACU,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAsBxC;;OAEG;IACI,UAAU,IAAI,IAAI;IAQzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;YACW,YAAY;IAsB1B,OAAO,CAAC,eAAe,CAA8C;IAErE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAShC;;OAEG;YACW,eAAe;IAW7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;YACW,aAAa;IAe3B;;OAEG;YACW,KAAK;IAoDnB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAMjC;;;;;OAKG;YACW,2BAA2B;IAuCzC;;OAEG;IACH,OAAO,CAAC,WAAW,CAA+C;IAElE;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;YACW,gBAAgB;CAyCjC"}
1
+ {"version":3,"file":"localCacheManager.d.ts","sourceRoot":"","sources":["../../src/generic/localCacheManager.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,50 @@ import { CompositeKey, KeyValuePair } from "./compositeKey.js";
7
7
  function LogStatusVerbose(message) {
8
8
  LogStatusEx({ message, verboseOnly: true });
9
9
  }
10
+ /**
11
+ * Recursively freezes a value that is about to enter the cache, so consumers holding the
12
+ * same reference cannot mutate shared state.
13
+ *
14
+ * Only invoked when the storage provider reports
15
+ * {@link ILocalStorageProvider.SharesReferences} — a serializing backend (IndexedDB,
16
+ * localStorage, Redis, MMKV) already isolates stored data, and freezing there would
17
+ * needlessly immobilize the caller's own rows.
18
+ *
19
+ * Freezing the ARRAY matters as much as the rows: `results.sort()` / `.push()` on a live
20
+ * cache array silently reorders or grows the cached slot for every later reader.
21
+ *
22
+ * Freezes BEFORE recursing, so the `isFrozen` short-circuit both skips already-frozen
23
+ * subtrees (cheap re-entry for in-place slot maintenance, which carries existing rows
24
+ * forward by reference) and terminates cycles.
25
+ *
26
+ * Two value kinds are skipped, not frozen — accepted residuals:
27
+ * - Binary payloads (`Buffer`/TypedArray/`ArrayBuffer`, e.g. `varbinary` columns): the spec
28
+ * makes `Object.freeze` THROW on a non-empty view, so attempting it would turn a cache
29
+ * write into a crash.
30
+ * - `Date` internal slots: `Object.freeze` cannot protect them — `setHours` and friends
31
+ * still work.
32
+ */
33
+ function deepFreezeCacheValue(value, visited = new WeakSet()) {
34
+ if (value === null || typeof value !== 'object'
35
+ || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
36
+ return value;
37
+ }
38
+ // Cycle termination and re-entry short-circuit key off an explicit visited set rather than
39
+ // `Object.isFrozen`. Those are not the same test: an object frozen SHALLOWLY by someone else
40
+ // (a caller that ran `Object.freeze(row)` before handing it over) reports frozen while its
41
+ // nested values are still writable, so keying off isFrozen would skip the whole subtree and
42
+ // leave shared state mutable. Already-frozen objects are cheap to re-freeze; unvisited
43
+ // children are the thing that must not be skipped.
44
+ if (visited.has(value)) {
45
+ return value;
46
+ }
47
+ visited.add(value);
48
+ Object.freeze(value);
49
+ for (const nested of Object.values(value)) {
50
+ deepFreezeCacheValue(nested, visited);
51
+ }
52
+ return value;
53
+ }
10
54
  // ============================================================================
11
55
  // DEFAULT CONFIGURATION
12
56
  // ============================================================================
@@ -76,6 +120,12 @@ export class LocalCacheManager extends BaseSingleton {
76
120
  constructor() {
77
121
  super();
78
122
  this._storageProvider = null;
123
+ /**
124
+ * Whether the active storage provider hands back live object references, resolved once at
125
+ * initialization — from the provider's declared {@link ILocalStorageProvider.SharesReferences}
126
+ * when it states one, otherwise measured empirically. Gates the defensive deep-freeze.
127
+ */
128
+ this._sharesReferences = false;
79
129
  this._registry = new Map();
80
130
  this._initialized = false;
81
131
  this._initializePromise = null;
@@ -138,14 +188,64 @@ export class LocalCacheManager extends BaseSingleton {
138
188
  this._initializePromise = this.doInitialize(storageProvider, config);
139
189
  return this._initializePromise;
140
190
  }
191
+ /**
192
+ * Decides whether the storage provider hands back live object references — the condition
193
+ * that makes the defensive deep-freeze necessary.
194
+ *
195
+ * Prefers the provider's declared {@link ILocalStorageProvider.SharesReferences}. When a
196
+ * provider does not state one (any implementation written before that property existed),
197
+ * MEASURE it rather than guessing: store a sentinel object, read it back, and compare
198
+ * identity. A reference-sharing store returns the very same object; anything with a
199
+ * serialization or structured-clone boundary returns a copy. This is what keeps the
200
+ * property optional — an external provider that never declares it still gets the correct
201
+ * protection instead of silently losing it to a falsy default.
202
+ *
203
+ * Fails closed to `false` if the probe cannot complete (a provider whose backing store is
204
+ * not ready at init): that matches the pre-freeze behavior rather than immobilizing rows
205
+ * for a provider we could not classify.
206
+ */
207
+ async resolveSharesReferences(storageProvider) {
208
+ if (typeof storageProvider.SharesReferences === 'boolean') {
209
+ return storageProvider.SharesReferences;
210
+ }
211
+ const probeKey = '__mj_sharesreferences_probe__';
212
+ const sentinel = { probe: true };
213
+ try {
214
+ await storageProvider.SetItem(probeKey, sentinel, CacheCategory.Default);
215
+ const readBack = await storageProvider.GetItem(probeKey, CacheCategory.Default);
216
+ const shares = readBack === sentinel;
217
+ LogStatusVerbose(`[CACHE-INIT] Storage provider "${storageProvider.constructor?.name ?? 'unknown'}" did not declare ` +
218
+ `SharesReferences; probed it as ${shares} (freeze-on-write ${shares ? 'ENABLED' : 'disabled'}).`);
219
+ return shares;
220
+ }
221
+ catch (e) {
222
+ LogError(`LocalCacheManager: could not probe SharesReferences on the storage provider; ` +
223
+ `assuming it isolates (freeze-on-write disabled). Declare SharesReferences to be explicit. ${e}`);
224
+ return false;
225
+ }
226
+ finally {
227
+ try {
228
+ await storageProvider.Remove(probeKey, CacheCategory.Default);
229
+ }
230
+ catch {
231
+ /* best-effort cleanup — a leftover probe key is harmless */
232
+ }
233
+ }
234
+ }
141
235
  /**
142
236
  * Internal initialization logic - only called once by the first caller
143
237
  */
144
238
  async doInitialize(storageProvider, config) {
145
- this._storageProvider = storageProvider;
146
239
  if (config) {
147
240
  this._config = { ...this._config, ...config };
148
241
  }
242
+ // Resolve the freeze decision BEFORE publishing the provider. The probe awaits I/O, and
243
+ // `_storageProvider` is what every write path reads to decide whether to freeze — so
244
+ // assigning it first opens a window where writes see the new provider paired with the
245
+ // PREVIOUS provider's (or the default `false`) freeze decision. Same ordering bug that
246
+ // `SetStorageProvider` had; fixed here too rather than left as the one asymmetric path.
247
+ this._sharesReferences = await this.resolveSharesReferences(storageProvider);
248
+ this._storageProvider = storageProvider;
149
249
  await this.loadRegistry();
150
250
  this._initialized = true;
151
251
  // Start periodic eviction sweep for TTL-expired entries
@@ -193,12 +293,24 @@ export class LocalCacheManager extends BaseSingleton {
193
293
  * @param newProvider - The new storage provider to use
194
294
  */
195
295
  async SetStorageProvider(newProvider) {
296
+ // The freeze decision belongs to the ACTIVE provider, not to whichever one happened to be
297
+ // installed at Initialize. MJAPI initializes on the in-memory provider during engine
298
+ // loading and swaps to Redis afterward, so these two have OPPOSITE reference semantics on
299
+ // every Redis deployment — carrying the old answer forward means freezing rows Redis has
300
+ // already isolated (all of the hazard, none of the protection), or, on the reverse swap,
301
+ // silently dropping the protection.
302
+ //
303
+ // Resolved BEFORE `_storageProvider` is published in both branches: the probe awaits I/O,
304
+ // and write paths read `_storageProvider` to decide whether to freeze, so publishing first
305
+ // would pair the new provider with the old provider's decision for the duration of the probe.
196
306
  if (!this._initialized) {
197
307
  // Not yet initialized — just set the provider and return
308
+ this._sharesReferences = await this.resolveSharesReferences(newProvider);
198
309
  this._storageProvider = newProvider;
199
310
  return;
200
311
  }
201
312
  const oldProvider = this._storageProvider;
313
+ this._sharesReferences = await this.resolveSharesReferences(newProvider);
202
314
  this._storageProvider = newProvider;
203
315
  // Migrate existing cached data from old provider to new provider
204
316
  const entries = this.GetAllEntries();
@@ -932,7 +1044,8 @@ export class LocalCacheManager extends BaseSingleton {
932
1044
  *
933
1045
  * @param name - The dataset name
934
1046
  * @param itemFilters - Optional filters applied to the dataset
935
- * @param dataset - The dataset result to cache
1047
+ * @param dataset - The dataset result to cache. Deep-frozen on reference-sharing storage,
1048
+ * like every other cache write funnel — see below.
936
1049
  * @param keyPrefix - Prefix for the cache key (typically includes connection info)
937
1050
  */
938
1051
  async SetDataset(name, itemFilters, dataset, keyPrefix) {
@@ -942,6 +1055,17 @@ export class LocalCacheManager extends BaseSingleton {
942
1055
  // Estimate size from a string representation (used only for cache eviction
943
1056
  // accounting; the actual stored value is the native object).
944
1057
  const sizeBytes = this.estimateSize(JSON.stringify(dataset));
1058
+ // Fourth write funnel, held to the same contract as SetRunViewResult /
1059
+ // SetRunQueryResult / storeCachedResults. `GetDataset` hands this object straight back
1060
+ // out, so on a reference-sharing provider every reader shares it — the same exposure the
1061
+ // other three close. It has no in-repo caller today (GetDatasetByName caches per ITEM via
1062
+ // SetRunViewResult), but it is exported public API, so an external caller would otherwise
1063
+ // get an unprotected slot with no indication that it differs from the documented rule.
1064
+ //
1065
+ // Frozen BEFORE the awaited eviction below, for the same reason as the other funnels: a
1066
+ // yield point between the decision to cache and the freeze is a window in which the
1067
+ // caller can still mutate what is about to become shared state.
1068
+ this.freezeRowDataIfProviderSharesReferences(dataset);
945
1069
  // Check if we need to evict entries
946
1070
  await this.evictIfNeeded(sizeBytes);
947
1071
  try {
@@ -1078,7 +1202,7 @@ export class LocalCacheManager extends BaseSingleton {
1078
1202
  * pre-RLS format so normal cache sharing is preserved and no existing entries are invalidated.
1079
1203
  * @returns A unique, human-readable fingerprint string
1080
1204
  */
1081
- GenerateRunViewFingerprint(params, connectionPrefix, rlsWhereClause) {
1205
+ GenerateRunViewFingerprint(params, connectionPrefix, rlsWhereClause, datasetSegment) {
1082
1206
  const entity = params.EntityName?.trim() || 'Unknown';
1083
1207
  const rawFilter = params.ExtraFilter;
1084
1208
  const filter = (typeof rawFilter === 'string' ? rawFilter : rawFilter ? JSON.stringify(rawFilter) : '').trim();
@@ -1158,6 +1282,25 @@ export class LocalCacheManager extends BaseSingleton {
1158
1282
  if (viewKey.length > 0) {
1159
1283
  parts.push(`vw:${viewKey}`);
1160
1284
  }
1285
+ // Dataset namespace. `GetDatasetByName` caches each dataset ITEM's rows through this same
1286
+ // builder, supplying only entity + the item's WhereClause — and every shipped item has a
1287
+ // NULL WhereClause, so without this segment a dataset item emits the identical fingerprint
1288
+ // to a plain unfiltered read of the same entity and the two silently share one slot. That
1289
+ // is not merely a stale-data risk: the MJ_Metadata dataset writes its rows with
1290
+ // `ProviderInternalScaffolding` (deliberately UNFROZEN, because bootstrap rearranges them
1291
+ // in place), so the shared slot hands ordinary callers unprotected rows for the hottest
1292
+ // entities in the process — and, in the other direction, an ordinary read repopulating an
1293
+ // evicted slot stores it FROZEN and the next metadata refresh throws.
1294
+ //
1295
+ // Dataset items may also project columns (`DatasetItem.Columns`), where a RunView slot is
1296
+ // always the full field set — so the two are not interchangeable in shape either.
1297
+ //
1298
+ // Appended ONLY when supplied, so ordinary reads keep their exact pre-existing key and no
1299
+ // existing cache entry is invalidated by this change.
1300
+ const dataset = (datasetSegment ?? '').trim();
1301
+ if (dataset.length > 0) {
1302
+ parts.push(`ds:${dataset}`);
1303
+ }
1161
1304
  // Only include connection if provided
1162
1305
  if (connection) {
1163
1306
  parts.push(connection);
@@ -1260,6 +1403,64 @@ export class LocalCacheManager extends BaseSingleton {
1260
1403
  return undefined;
1261
1404
  }
1262
1405
  }
1406
+ /**
1407
+ * Deep-freezes an about-to-be-stored cache payload when — and only when — the active
1408
+ * storage provider hands out live object references
1409
+ * ({@link ILocalStorageProvider.SharesReferences}).
1410
+ *
1411
+ * This is the cache's structural defense against consumer corruption. Under a
1412
+ * reference-sharing provider the rows a caller receives ARE the cached rows, in both
1413
+ * directions: on a hit the reader gets the stored array, and on a miss the cache stored
1414
+ * the caller's own array. Any in-place mutation therefore edits process-wide state. One
1415
+ * such mutation shipped as a P1 (a resolver renamed `__mj_CreatedAt` to its GraphQL
1416
+ * transport alias in place, so every later read served rows `BaseEntity.SetMany`
1417
+ * rejects). Freezing makes that failure immediate and attributable — a `TypeError` at
1418
+ * the offending line — instead of silent corruption, and costs nothing per cache hit.
1419
+ *
1420
+ * On serializing providers this is a no-op: their stored data is already isolated, and
1421
+ * freezing would only immobilize the caller's own rows for no safety gain.
1422
+ *
1423
+ * @param payload - The envelope being handed to the storage provider. Frozen in place;
1424
+ * the same reference is returned for call-site convenience.
1425
+ */
1426
+ /**
1427
+ * Whether the CURRENTLY-INSTALLED provider hands back live references.
1428
+ *
1429
+ * Prefers the active provider's own declaration, read live on each call — a property read,
1430
+ * so it costs nothing on the write path, and it stays correct no matter how many times the
1431
+ * provider is swapped or which code path does the swapping. `_sharesReferences` (resolved at
1432
+ * `Initialize`/`SetStorageProvider`) is the fallback for providers that declare nothing, where
1433
+ * the answer can only come from the async probe and therefore cannot be recomputed here.
1434
+ *
1435
+ * Belt-and-braces with the re-resolution in {@link SetStorageProvider}: that keeps the probed
1436
+ * value correct across swaps, and this keeps DECLARED providers correct even if some future
1437
+ * swap site forgets to re-resolve.
1438
+ */
1439
+ activeProviderSharesReferences() {
1440
+ const declared = this._storageProvider?.SharesReferences;
1441
+ return typeof declared === 'boolean' ? declared : this._sharesReferences;
1442
+ }
1443
+ freezeRowDataIfProviderSharesReferences(payload) {
1444
+ if (!this.activeProviderSharesReferences()) {
1445
+ return payload;
1446
+ }
1447
+ try {
1448
+ return deepFreezeCacheValue(payload);
1449
+ }
1450
+ catch (e) {
1451
+ // The freeze is protective, never load-bearing — an exotic value Object.freeze
1452
+ // rejects (beyond the guarded binary kinds) must degrade to a stored write rather
1453
+ // than taking down the read path it defends.
1454
+ //
1455
+ // The payload is PARTIALLY frozen at this point and cannot be un-frozen: the walk
1456
+ // freezes parent-first, so everything visited before the throw is already immutable.
1457
+ // Say that plainly instead of claiming "unfrozen" — an operator debugging a
1458
+ // downstream TypeError needs to know the entry is a mix, not a clean opt-out.
1459
+ LogError(`LocalCacheManager: freeze-on-write failed partway; storing the entry with ` +
1460
+ `whatever was frozen before the failure (partial protection, not none). ${e}`);
1461
+ return payload;
1462
+ }
1463
+ }
1263
1464
  /**
1264
1465
  * Stores a RunView result in the cache.
1265
1466
  *
@@ -1276,8 +1477,11 @@ export class LocalCacheManager extends BaseSingleton {
1276
1477
  * AllowCaching gating in multi-provider scenarios (parallel client connections to multiple
1277
1478
  * servers). Falls back to `Metadata.Provider` (global default) when omitted, which is fine
1278
1479
  * for single-provider apps but wrong when AllowCaching differs across servers.
1480
+ * @param ttlMs - Optional time-based expiry (required for external-data-source entities).
1481
+ * @param options - See {@link CacheWriteOptions}. Pass `{ ProviderInternalScaffolding: true }`
1482
+ * only for slots the writing provider is the sole consumer of.
1279
1483
  */
1280
- async SetRunViewResult(fingerprint, params, results, maxUpdatedAt, aggregateResults, totalRowCount, provider, ttlMs) {
1484
+ async SetRunViewResult(fingerprint, params, results, maxUpdatedAt, aggregateResults, totalRowCount, provider, ttlMs, options) {
1281
1485
  if (!this._storageProvider || !this._config.enabled)
1282
1486
  return;
1283
1487
  // Keyset (AfterKey) queries are inherently single-use — each call uses a different
@@ -1336,6 +1540,10 @@ export class LocalCacheManager extends BaseSingleton {
1336
1540
  }
1337
1541
  // Persist results, maxUpdatedAt, aggregateResults, totalRowCount, and schemaHash
1338
1542
  const data = { results, maxUpdatedAt };
1543
+ if (options?.ProviderInternalScaffolding) {
1544
+ // Persisted so event-driven in-place maintenance carries the exemption forward.
1545
+ data.providerInternalScaffolding = true;
1546
+ }
1339
1547
  if (aggregateResults && aggregateResults.length > 0) {
1340
1548
  data.aggregateResults = aggregateResults;
1341
1549
  }
@@ -1361,10 +1569,23 @@ export class LocalCacheManager extends BaseSingleton {
1361
1569
  LogStatusEx({ message: `[CACHE-WRITE-GATE] Skipping cache write for "${params.EntityName || fingerprint.substring(0, 60)}" — estimated entry size ${sizeBytes} bytes exceeds per-entry cap (${this._config.maxEntryPercentOfCache}% of ${this._config.maxSizeBytes} byte budget)` });
1362
1570
  return;
1363
1571
  }
1364
- // Per-entity memory limit: evict oldest entries for this entity if over budget
1572
+ // The oversized gate above is the ONLY step that can decline this write, and it is
1573
+ // synchronous — so by here the row set is definitely becoming shared state, and it is
1574
+ // frozen with no intervening yield point. That ordering is load-bearing: the eviction
1575
+ // steps below are awaited, and callers hold this very array while they run (the
1576
+ // smart-cache stale leg does not await this method at all). Freezing after them leaves
1577
+ // a window in which shared rows are handed out still mutable — and `BaseEntity`
1578
+ // samples `Object.isFrozen` once at load, so a freeze arriving mid-construction makes
1579
+ // a later field READ throw. Declining writes still leave the caller's rows mutable,
1580
+ // because the decline happens before this point.
1581
+ if (!options?.ProviderInternalScaffolding) {
1582
+ this.freezeRowDataIfProviderSharesReferences(data);
1583
+ }
1584
+ // Per-entity memory limit: evict oldest entries for this entity if over budget.
1585
+ // Evicts OTHER entries only — it cannot cancel this write.
1365
1586
  const entityName = params.EntityName || 'Unknown';
1366
1587
  await this.enforcePerEntityMemoryLimit(entityName, sizeBytes);
1367
- // Check if we need to evict entries (global budget)
1588
+ // Check if we need to evict entries (global budget). Also eviction-only.
1368
1589
  await this.evictIfNeeded(sizeBytes);
1369
1590
  try {
1370
1591
  // Native object storage — IDB structured-clones, localStorage / Redis serialize internally.
@@ -1504,6 +1725,8 @@ export class LocalCacheManager extends BaseSingleton {
1504
1725
  totalRowCount: parsed.totalRowCount,
1505
1726
  // Surfaced so in-place maintenance can carry it forward on rewrite (B38).
1506
1727
  schemaHash: parsed.schemaHash,
1728
+ // Same carry-forward rationale: a maintained scaffolding slot must stay exempt.
1729
+ providerInternalScaffolding: parsed.providerInternalScaffolding,
1507
1730
  };
1508
1731
  if (parsed.aggregateResults) {
1509
1732
  result.aggregateResults = parsed.aggregateResults;
@@ -1717,7 +1940,8 @@ export class LocalCacheManager extends BaseSingleton {
1717
1940
  // Upsert the entity (add or replace)
1718
1941
  resultMap.set(keyStr, entityData);
1719
1942
  const updatedResults = Array.from(resultMap.values());
1720
- return await this.storeCachedResults(fingerprint, updatedResults, newMaxUpdatedAt, { totalRowCount: cached.totalRowCount, rowCount: cached.results.length, schemaHash: cached.schemaHash });
1943
+ return await this.storeCachedResults(fingerprint, updatedResults, newMaxUpdatedAt, { totalRowCount: cached.totalRowCount, rowCount: cached.results.length, schemaHash: cached.schemaHash,
1944
+ providerInternalScaffolding: cached.providerInternalScaffolding });
1721
1945
  }
1722
1946
  catch (e) {
1723
1947
  LogError(`LocalCacheManager.UpsertSingleEntity failed: ${e}`);
@@ -1759,7 +1983,8 @@ export class LocalCacheManager extends BaseSingleton {
1759
1983
  }
1760
1984
  resultMap.delete(keyStr);
1761
1985
  const updatedResults = Array.from(resultMap.values());
1762
- return await this.storeCachedResults(fingerprint, updatedResults, newMaxUpdatedAt, { totalRowCount: cached.totalRowCount, rowCount: cached.results.length, schemaHash: cached.schemaHash });
1986
+ return await this.storeCachedResults(fingerprint, updatedResults, newMaxUpdatedAt, { totalRowCount: cached.totalRowCount, rowCount: cached.results.length, schemaHash: cached.schemaHash,
1987
+ providerInternalScaffolding: cached.providerInternalScaffolding });
1763
1988
  }
1764
1989
  catch (e) {
1765
1990
  LogError(`LocalCacheManager.RemoveSingleEntity failed: ${e}`);
@@ -1800,6 +2025,12 @@ export class LocalCacheManager extends BaseSingleton {
1800
2025
  if (prior?.schemaHash) {
1801
2026
  data.schemaHash = prior.schemaHash;
1802
2027
  }
2028
+ // Carry the freeze exemption forward too — a scaffolding slot that gets maintained in
2029
+ // place must not silently become frozen, or the owner that mutates those rows breaks on
2030
+ // the next read (for the metadata dataset that means booting with no metadata).
2031
+ if (prior?.providerInternalScaffolding) {
2032
+ data.providerInternalScaffolding = true;
2033
+ }
1803
2034
  // Aggregates are deliberately NOT carried here — see hasAggregates(): an aggregate-bearing
1804
2035
  // slot is invalidated on mutation rather than maintained, so this path never runs for one.
1805
2036
  if (prior?.totalRowCount != null) {
@@ -1810,6 +2041,13 @@ export class LocalCacheManager extends BaseSingleton {
1810
2041
  // value is the native object. This runs on every save/delete event per matching
1811
2042
  // unfiltered fingerprint, so avoiding a full serialization here matters most.
1812
2043
  const sizeBytes = this.estimateResultsSize(updatedResults);
2044
+ // Second write funnel — this path bypasses SetRunViewResult entirely, so it must
2045
+ // freeze too. Rows carried forward from the prior slot are already frozen (the
2046
+ // isFrozen short-circuit makes re-entry cheap); what this catches is the NEW array
2047
+ // and the freshly upserted row. Scaffolding slots stay exempt (see above).
2048
+ if (!prior?.providerInternalScaffolding) {
2049
+ this.freezeRowDataIfProviderSharesReferences(data);
2050
+ }
1813
2051
  await this._storageProvider.SetItem(fingerprint, data, CacheCategory.RunViewCache);
1814
2052
  const existingEntry = this._registry.get(fingerprint);
1815
2053
  if (existingEntry) {
@@ -1911,7 +2149,14 @@ export class LocalCacheManager extends BaseSingleton {
1911
2149
  LogStatusEx({ message: `[CACHE-WRITE-GATE] Skipping cache write for query "${queryName}" — estimated entry size ${sizeBytes} bytes exceeds per-entry cap (${this._config.maxEntryPercentOfCache}% of ${this._config.maxSizeBytes} byte budget)` });
1912
2150
  return;
1913
2151
  }
1914
- // Check if we need to evict entries
2152
+ // Same reference-sharing exposure as the RunView path (GetRunQueryResult hands
2153
+ // `results` straight back out) — closed here rather than waiting for a mutator to
2154
+ // find it. Placed immediately after the only declining gate and BEFORE the awaited
2155
+ // eviction below, for the same reason as SetRunViewResult: callers of this method do
2156
+ // not always await it, so any yield point before the freeze is a window in which the
2157
+ // caller can still mutate the rows the cache is about to store.
2158
+ this.freezeRowDataIfProviderSharesReferences(data);
2159
+ // Check if we need to evict entries. Evicts OTHER entries only — cannot cancel this write.
1915
2160
  await this.evictIfNeeded(sizeBytes);
1916
2161
  const now = Date.now();
1917
2162
  const expiresAt = ttlMs ? now + ttlMs : undefined;