@iamjulianacosta/mobx-data 1.1.1 → 1.4.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.
- package/README.md +273 -102
- package/dist/{CacheHandler-BTU_rYkv.js → CacheHandler-BhfbVHed.js} +17 -20
- package/dist/CacheHandler-BhfbVHed.js.map +1 -0
- package/dist/{CacheHandler-CXgY9IJo.cjs → CacheHandler-Q5VXOgh9.cjs} +2 -2
- package/dist/CacheHandler-Q5VXOgh9.cjs.map +1 -0
- package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js +173 -0
- package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js.map +1 -0
- package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs +2 -0
- package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs.map +1 -0
- package/dist/{JsonApiSerializer-wndq5a1n.js → JsonApiSerializer-BV61cFAZ.js} +3 -3
- package/dist/JsonApiSerializer-BV61cFAZ.js.map +1 -0
- package/dist/{JsonApiSerializer-Bc4iQB0d.cjs → JsonApiSerializer-Dt_Y_FIo.cjs} +2 -2
- package/dist/JsonApiSerializer-Dt_Y_FIo.cjs.map +1 -0
- package/dist/JsonSerializer-BzUCyUSf.cjs +2 -0
- package/dist/JsonSerializer-BzUCyUSf.cjs.map +1 -0
- package/dist/JsonSerializer-CFqo6GjC.js +98 -0
- package/dist/JsonSerializer-CFqo6GjC.js.map +1 -0
- package/dist/MdqlMemoryExecutor-BUlsalKm.cjs +2 -0
- package/dist/MdqlMemoryExecutor-BUlsalKm.cjs.map +1 -0
- package/dist/MdqlMemoryExecutor-BWMP31zG.js +127 -0
- package/dist/MdqlMemoryExecutor-BWMP31zG.js.map +1 -0
- package/dist/{MemoryAdapter-ni25N4H0.js → MemoryAdapter-BW1HKixm.js} +2 -2
- package/dist/{MemoryAdapter-ni25N4H0.js.map → MemoryAdapter-BW1HKixm.js.map} +1 -1
- package/dist/{MemoryAdapter-BTK2D64s.cjs → MemoryAdapter-C8iXAa2v.cjs} +2 -2
- package/dist/{MemoryAdapter-BTK2D64s.cjs.map → MemoryAdapter-C8iXAa2v.cjs.map} +1 -1
- package/dist/{ODataAdapter-DAja_jKM.js → ODataAdapter-CeBJblLQ.js} +25 -22
- package/dist/ODataAdapter-CeBJblLQ.js.map +1 -0
- package/dist/{ODataAdapter-lMifLyLD.cjs → ODataAdapter-DdE6MWkG.cjs} +2 -2
- package/dist/ODataAdapter-DdE6MWkG.cjs.map +1 -0
- package/dist/RestAdapter-D7GSrsJo.cjs +2 -0
- package/dist/RestAdapter-D7GSrsJo.cjs.map +1 -0
- package/dist/{RestAdapter-CGWqOR_G.js → RestAdapter-DYUoyV5h.js} +112 -77
- package/dist/RestAdapter-DYUoyV5h.js.map +1 -0
- package/dist/SchemaService-C_pkh-vI.js +180 -0
- package/dist/SchemaService-C_pkh-vI.js.map +1 -0
- package/dist/SchemaService-DbJLoYb9.cjs +2 -0
- package/dist/SchemaService-DbJLoYb9.cjs.map +1 -0
- package/dist/Serializer-Bap9U-kR.cjs +2 -0
- package/dist/Serializer-Bap9U-kR.cjs.map +1 -0
- package/dist/{Serializer-FxJbsZ50.js → Serializer-Ca6w_QNQ.js} +63 -49
- package/dist/Serializer-Ca6w_QNQ.js.map +1 -0
- package/dist/adapter/index.cjs +1 -1
- package/dist/adapter/index.js +2 -2
- package/dist/cache/cache-utils.d.ts +1 -1
- package/dist/cache/cache-utils.d.ts.map +1 -1
- package/dist/createStore-7PecKT54.cjs +2 -0
- package/dist/createStore-7PecKT54.cjs.map +1 -0
- package/dist/createStore-BfmRfZ_2.js +1229 -0
- package/dist/createStore-BfmRfZ_2.js.map +1 -0
- package/dist/date-Bj4O2W1F.js.map +1 -1
- package/dist/date-CRCe-9gf.cjs.map +1 -1
- package/dist/decorators-CKneHgoF.js +56 -0
- package/dist/decorators-CKneHgoF.js.map +1 -0
- package/dist/decorators-DCVYKzrL.cjs +2 -0
- package/dist/decorators-DCVYKzrL.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -90
- package/dist/index.js.map +1 -1
- package/dist/inspector/ConsoleInspector.d.ts +49 -0
- package/dist/inspector/ConsoleInspector.d.ts.map +1 -0
- package/dist/inspector/DevToolsBridge.d.ts +21 -0
- package/dist/inspector/DevToolsBridge.d.ts.map +1 -0
- package/dist/inspector/QueryParser.d.ts +21 -0
- package/dist/inspector/QueryParser.d.ts.map +1 -0
- package/dist/inspector/StoreInspector.d.ts +31 -0
- package/dist/inspector/StoreInspector.d.ts.map +1 -0
- package/dist/inspector/index.cjs +17 -0
- package/dist/inspector/index.cjs.map +1 -0
- package/dist/inspector/index.d.ts +9 -0
- package/dist/inspector/index.d.ts.map +1 -0
- package/dist/inspector/index.js +896 -0
- package/dist/inspector/index.js.map +1 -0
- package/dist/inspector/integration.d.ts +15 -0
- package/dist/inspector/integration.d.ts.map +1 -0
- package/dist/inspector/serialization.d.ts +7 -0
- package/dist/inspector/serialization.d.ts.map +1 -0
- package/dist/inspector/types.d.ts +139 -0
- package/dist/inspector/types.d.ts.map +1 -0
- package/dist/json-api/index.cjs +1 -1
- package/dist/json-api/index.js +1 -1
- package/dist/mdql/MdqlMemoryExecutor.d.ts +17 -0
- package/dist/mdql/MdqlMemoryExecutor.d.ts.map +1 -0
- package/dist/mdql/MdqlQueryBuilder.d.ts +38 -0
- package/dist/mdql/MdqlQueryBuilder.d.ts.map +1 -0
- package/dist/mdql/MdqlValidator.d.ts +13 -0
- package/dist/mdql/MdqlValidator.d.ts.map +1 -0
- package/dist/mdql/index.d.ts +6 -0
- package/dist/mdql/index.d.ts.map +1 -0
- package/dist/mdql/types.d.ts +48 -0
- package/dist/mdql/types.d.ts.map +1 -0
- package/dist/model/Model.d.ts +4 -0
- package/dist/model/Model.d.ts.map +1 -1
- package/dist/model/Snapshot.d.ts +2 -0
- package/dist/model/Snapshot.d.ts.map +1 -1
- package/dist/model/index.cjs +1 -1
- package/dist/model/index.js +1 -1
- package/dist/odata/ODataAdapter.d.ts.map +1 -1
- package/dist/odata/index.cjs +1 -1
- package/dist/odata/index.js +1 -1
- package/dist/relationships-BgM0NKdb.cjs +2 -0
- package/dist/relationships-BgM0NKdb.cjs.map +1 -0
- package/dist/{relationships-BEXANmWg.js → relationships-DvSi8fVN.js} +37 -28
- package/dist/relationships-DvSi8fVN.js.map +1 -0
- package/dist/request/CacheHandler.d.ts.map +1 -1
- package/dist/request/index.cjs +1 -1
- package/dist/request/index.js +1 -1
- package/dist/schema/SchemaService.d.ts +38 -1
- package/dist/schema/SchemaService.d.ts.map +1 -1
- package/dist/schema/decorators.d.ts +20 -1
- package/dist/schema/decorators.d.ts.map +1 -1
- package/dist/schema/index.cjs +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +10 -8
- package/dist/schema/types.d.ts +31 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/serializer/JsonSerializer.d.ts +2 -0
- package/dist/serializer/JsonSerializer.d.ts.map +1 -1
- package/dist/serializer/Serializer.d.ts +9 -0
- package/dist/serializer/Serializer.d.ts.map +1 -1
- package/dist/serializer/index.cjs +1 -1
- package/dist/serializer/index.js +6 -5
- package/dist/serializer/index.js.map +1 -1
- package/dist/store/Store.d.ts +3 -0
- package/dist/store/Store.d.ts.map +1 -1
- package/dist/store/createStore.d.ts +12 -0
- package/dist/store/createStore.d.ts.map +1 -0
- package/dist/store/index.cjs +1 -1
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +5 -4
- package/dist/types-CC2fG3FP.js +8 -0
- package/dist/types-CC2fG3FP.js.map +1 -0
- package/dist/types-DCLy5XYj.cjs +2 -0
- package/dist/types-DCLy5XYj.cjs.map +1 -0
- package/package.json +7 -1
- package/src/cache/cache-utils.ts +4 -4
- package/src/index.ts +3 -0
- package/src/inspector/ConsoleInspector.ts +470 -0
- package/src/inspector/DevToolsBridge.ts +214 -0
- package/src/inspector/QueryParser.ts +343 -0
- package/src/inspector/StoreInspector.ts +162 -0
- package/src/inspector/index.ts +20 -0
- package/src/inspector/integration.ts +56 -0
- package/src/inspector/serialization.ts +100 -0
- package/src/inspector/types.ts +161 -0
- package/src/mdql/MdqlMemoryExecutor.ts +229 -0
- package/src/mdql/MdqlQueryBuilder.ts +170 -0
- package/src/mdql/MdqlValidator.ts +193 -0
- package/src/mdql/index.ts +21 -0
- package/src/mdql/types.ts +107 -0
- package/src/model/Model.ts +15 -0
- package/src/model/Snapshot.ts +3 -0
- package/src/odata/ODataAdapter.ts +4 -1
- package/src/request/CacheHandler.ts +2 -6
- package/src/schema/SchemaService.ts +123 -1
- package/src/schema/decorators.ts +29 -0
- package/src/schema/index.ts +1 -1
- package/src/schema/types.ts +34 -0
- package/src/serializer/JsonSerializer.ts +14 -2
- package/src/serializer/Serializer.ts +24 -1
- package/src/store/Store.ts +61 -18
- package/src/store/createStore.ts +39 -0
- package/src/store/index.ts +1 -0
- package/dist/CacheHandler-BTU_rYkv.js.map +0 -1
- package/dist/CacheHandler-CXgY9IJo.cjs.map +0 -1
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs +0 -2
- package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs.map +0 -1
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js +0 -261
- package/dist/EmbeddedRecordsMixin-VoHluHCT.js.map +0 -1
- package/dist/JsonApiSerializer-Bc4iQB0d.cjs.map +0 -1
- package/dist/JsonApiSerializer-wndq5a1n.js.map +0 -1
- package/dist/ODataAdapter-DAja_jKM.js.map +0 -1
- package/dist/ODataAdapter-lMifLyLD.cjs.map +0 -1
- package/dist/RestAdapter-1V94stW-.cjs +0 -2
- package/dist/RestAdapter-1V94stW-.cjs.map +0 -1
- package/dist/RestAdapter-CGWqOR_G.js.map +0 -1
- package/dist/SchemaService-DZwkFgZu.js +0 -102
- package/dist/SchemaService-DZwkFgZu.js.map +0 -1
- package/dist/SchemaService-Di_yjVzU.cjs +0 -2
- package/dist/SchemaService-Di_yjVzU.cjs.map +0 -1
- package/dist/Serializer-95gi5edy.cjs +0 -2
- package/dist/Serializer-95gi5edy.cjs.map +0 -1
- package/dist/Serializer-FxJbsZ50.js.map +0 -1
- package/dist/Store-KvjmBTQ9.cjs +0 -2
- package/dist/Store-KvjmBTQ9.cjs.map +0 -1
- package/dist/Store-mvrDLQEZ.js +0 -957
- package/dist/Store-mvrDLQEZ.js.map +0 -1
- package/dist/cache-utils-2lswvJ87.cjs +0 -2
- package/dist/cache-utils-2lswvJ87.cjs.map +0 -1
- package/dist/cache-utils-38Dqu4Qf.js +0 -39
- package/dist/cache-utils-38Dqu4Qf.js.map +0 -1
- package/dist/decorators-HQ1KnRdh.cjs +0 -2
- package/dist/decorators-HQ1KnRdh.cjs.map +0 -1
- package/dist/decorators-Zr35qr6A.js +0 -50
- package/dist/decorators-Zr35qr6A.js.map +0 -1
- package/dist/relationships-B55LBaCW.cjs +0 -2
- package/dist/relationships-B55LBaCW.cjs.map +0 -1
- package/dist/relationships-BEXANmWg.js.map +0 -1
- package/dist/types-C9NB2gRj.js +0 -7
- package/dist/types-C9NB2gRj.js.map +0 -1
- package/dist/types-uWOXMPWW.cjs +0 -2
- package/dist/types-uWOXMPWW.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Store-mvrDLQEZ.js","sources":["../src/store/IdentityMap.ts","../src/store/RecordArray.ts","../src/store/Store.ts"],"sourcesContent":["/**\n * Two-level observable map that serves as the store's record cache.\n *\n * Records are stored in per-type buckets:\n * ```\n * buckets: Map<modelName, Map<id, Model>>\n * ```\n *\n * The outer map is MobX-observable (shallow) so derived views like `peekAll`\n * react when new type buckets are added. Each inner bucket is an observable\n * map so computed properties that iterate records within a type react to\n * additions and deletions.\n *\n * All mutating methods (`set`, `delete`, `clear`) are MobX `action`s so they\n * batch observable updates correctly.\n */\n\nimport { makeObservable, observable, action } from 'mobx';\nimport type { Model } from '@mobx-data/model';\n\nexport class IdentityMap {\n /** @internal */\n readonly _buckets: Map<string, Map<string, Model>> = new Map();\n\n constructor() {\n makeObservable<this, '_buckets'>(this, {\n _buckets: observable.shallow,\n set: action,\n delete: action,\n clear: action,\n });\n }\n\n /**\n * Returns the bucket for `modelName`, optionally creating it when absent.\n * Internal helper — not part of the public API.\n */\n private bucket(modelName: string, create = false): Map<string, Model> | undefined {\n let existing = this._buckets.get(modelName);\n if (!existing && create) {\n existing = observable.map<string, Model>({}, { deep: false });\n this._buckets.set(modelName, existing);\n }\n return existing;\n }\n\n /** Adds or replaces the record with the given `id` under `modelName`. */\n set(modelName: string, id: string, record: Model): void {\n const bucket = this.bucket(modelName, true)!;\n bucket.set(id, record);\n }\n\n /**\n * Returns the record for `modelName` + `id`, or `null` when not found.\n */\n get(modelName: string, id: string): Model | null {\n return this.bucket(modelName)?.get(id) ?? null;\n }\n\n /** Returns `true` when a record exists for `modelName` + `id`. */\n has(modelName: string, id: string): boolean {\n return this.bucket(modelName)?.has(id) ?? false;\n }\n\n /**\n * Removes the record for `modelName` + `id`.\n * @returns `true` when the record existed and was deleted.\n */\n delete(modelName: string, id: string): boolean {\n return this.bucket(modelName)?.delete(id) ?? false;\n }\n\n /** Returns all records stored under `modelName` as an array. */\n all(modelName: string): Model[] {\n const bucket = this.bucket(modelName);\n if (!bucket) {\n return [];\n }\n return Array.from(bucket.values());\n }\n\n /**\n * Clears all records for `modelName`, or all records across all types when\n * `modelName` is omitted.\n */\n clear(modelName?: string): void {\n if (modelName) {\n this.bucket(modelName)?.clear();\n } else {\n for (const bucket of this._buckets.values()) {\n bucket.clear();\n }\n }\n }\n\n /**\n * Returns the number of records stored for `modelName`, or the total across\n * all types when `modelName` is omitted.\n */\n size(modelName?: string): number {\n if (modelName) {\n return this.bucket(modelName)?.size ?? 0;\n }\n let total = 0;\n for (const bucket of this._buckets.values()) {\n total += bucket.size;\n }\n return total;\n }\n}\n","/**\n * Observable array proxies for store query results.\n *\n * Two classes are provided:\n *\n * ## `RecordArray<T>`\n * A live, read-only view of all records of a given type in the store's\n * identity map. The contents are derived via an injected `source` function\n * so they stay in sync automatically with the identity map.\n *\n * Supports `update()` to trigger a background re-fetch if an `update` callback\n * is provided.\n *\n * ## `AdapterPopulatedRecordArray<T>`\n * A subclass used for the results of `store.query()`. Unlike `RecordArray`,\n * its contents are determined by the last adapter response (order preserved,\n * no auto-sync with new pushes).\n *\n * Adds `meta`, `links`, and `query` properties that are set by the store after\n * each adapter call.\n */\n\nimport { makeObservable, computed, observable } from 'mobx';\nimport type { Model } from '@mobx-data/model';\n\n/** Constructor options for `RecordArray`. */\nexport interface RecordArrayOptions<T extends Model> {\n /** Registered model name. */\n modelName: string;\n /** Function that returns the current record list (called on each access). */\n source: () => T[];\n /** Optional async callback invoked by `update()`. */\n update?: () => Promise<void>;\n /**\n * When `true`, the internal MobX computed retains its cached value even when\n * no observers are actively subscribed. Prevents expensive recomputation\n * for long-lived filtered views (e.g. `liveQuery` results).\n */\n keepAlive?: boolean;\n}\n\n/**\n * Live, read-only view of all records of a given type.\n *\n * The `source` function is called on each observable access so the array\n * always reflects the current store state. MobX tracks the `source` call\n * as part of `resolved`, so any computed prop that reads from this array\n * will re-run when the underlying identity map changes.\n */\nexport class RecordArray<T extends Model = Model> implements Iterable<T> {\n private readonly opts: RecordArrayOptions<T>;\n\n /** `true` while `update()` is in progress. */\n protected updating: boolean = false;\n\n constructor(opts: RecordArrayOptions<T>) {\n this.opts = opts;\n makeObservable<this, 'resolved' | 'updating'>(this, {\n resolved: opts.keepAlive ? computed({ keepAlive: true }) : computed,\n updating: observable,\n length: computed,\n modelName: computed,\n });\n }\n\n /** Current record list, derived from the injected `source` function. */\n protected get resolved(): T[] {\n return this.opts.source();\n }\n\n /** `true` while a background `update()` call is in progress. */\n get isLoading(): boolean {\n return this.updating;\n }\n\n /** Alias for `isLoading`. */\n get isUpdating(): boolean {\n return this.updating;\n }\n\n /** Number of records in the array. */\n get length(): number {\n return this.resolved.length;\n }\n\n /** The registered model name for the records in this array. */\n get modelName(): string {\n return this.opts.modelName;\n }\n\n /** Returns the record at `index`, or `undefined`. */\n at(index: number): T | undefined {\n return this.resolved[index];\n }\n\n /** Returns a plain array snapshot of all records. */\n toArray(): T[] {\n return [...this.resolved];\n }\n\n /** Maps over records. */\n map<R>(callback: (record: T, i: number) => R): R[] {\n return this.resolved.map(callback);\n }\n\n /** Filters records. */\n filter(predicate: (record: T, i: number) => boolean): T[] {\n return this.resolved.filter(predicate);\n }\n\n /** Iterates records. */\n forEach(callback: (record: T, i: number) => void): void {\n this.resolved.forEach(callback);\n }\n\n /** Returns `true` when `record` is in the array. */\n includes(record: T): boolean {\n return this.resolved.includes(record);\n }\n\n /**\n * Triggers the `update` callback (if any) to refresh the array from the\n * adapter. Sets `isLoading` while the request is in flight.\n */\n async update(): Promise<this> {\n if (!this.opts.update) {\n return this;\n }\n this.updating = true;\n try {\n await this.opts.update();\n } finally {\n this.updating = false;\n }\n return this;\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.resolved[Symbol.iterator]();\n }\n}\n\n/** Constructor options for `AdapterPopulatedRecordArray`. */\nexport interface AdapterPopulatedRecordArrayOptions<T extends Model>\n extends RecordArrayOptions<T> {\n /** Query parameters that produced this result set. */\n query: Record<string, unknown>;\n /** Server-side metadata (pagination, total counts, etc.). */\n meta?: Record<string, unknown>;\n /** Pagination or related links. */\n links?: Record<string, string>;\n}\n\n/**\n * Record array populated by an adapter query response.\n *\n * The store creates one of these for each `store.query()` call. Its contents\n * are driven by the id list returned from the last adapter call, not by live\n * identity map iteration.\n *\n * Call `.update()` to re-issue the original query and refresh the contents.\n */\nexport class AdapterPopulatedRecordArray<\n T extends Model = Model,\n> extends RecordArray<T> {\n private queryParams: Record<string, unknown>;\n\n private metaData: Record<string, unknown>;\n\n private linksData: Record<string, string>;\n\n constructor(opts: AdapterPopulatedRecordArrayOptions<T>) {\n super(opts);\n this.queryParams = opts.query;\n this.metaData = opts.meta ?? {};\n this.linksData = opts.links ?? {};\n makeObservable<this, 'metaData' | 'linksData'>(this, {\n metaData: observable.ref,\n linksData: observable.ref,\n meta: computed,\n links: computed,\n query: computed,\n });\n }\n\n /** Server-side metadata attached to the last response (e.g. pagination). */\n get meta(): Record<string, unknown> {\n return this.metaData;\n }\n\n /** Links attached to the last response. */\n get links(): Record<string, string> {\n return this.linksData;\n }\n\n /** The query parameters that produced this array. */\n get query(): Record<string, unknown> {\n return this.queryParams;\n }\n\n /** Called by the store to update `meta` after a successful query. */\n _setMeta(meta: Record<string, unknown>): void {\n this.metaData = meta;\n }\n\n /** Called by the store to update `links` after a successful query. */\n _setLinks(links: Record<string, string>): void {\n this.linksData = links;\n }\n}\n","/**\n * Central store — the top-level coordinator for the mobx-data runtime.\n *\n * `Store` orchestrates every aspect of the data layer:\n *\n * - **Identity Map** — a two-level `IdentityMap` keyed by `modelName → id`.\n * Records are merged in-place on repeated `push` calls so live references\n * always reflect the latest server state.\n *\n * - **Finding records** — `findRecord`, `findAll`, `query`, `queryRecord`\n * delegate to the registered adapter, then pass the raw response through the\n * registered serializer before pushing normalized data into the identity map.\n *\n * - **Saving records** — `saveRecord` calls `adapter.createRecord` or\n * `adapter.updateRecord` depending on `record.isNew`, then applies the\n * server response back onto the record via `_applyServerData`.\n *\n * - **Relationships** — `resolveRelationship` returns sync (`ManyArray`) or\n * async (`AsyncBelongsTo` / `AsyncHasMany`) proxy objects backed by the\n * store. `setRelationshipValue` updates `belongsTo` refs and keeps their\n * inverses in sync. `_hasManyAppend` / `_hasManyRemove` manage `hasMany`\n * refs and their inverses.\n *\n * - **Inverse tracking** — `addInverse` / `removeInverse` keep both sides of\n * a declared `inverse` relationship consistent when either side is mutated.\n *\n * ## Registration\n *\n * ```ts\n * store.registerAdapter('application', new RestAdapter());\n * store.registerSerializer('application', new JsonSerializer());\n * ```\n *\n * Adapters and serializers are looked up first by exact model name, then by\n * the special `'application'` fallback.\n */\n\nimport {\n singleton, inject, injectable,\n} from 'tsyringe';\nimport { runInAction, observable, computed, makeObservable } from 'mobx';\nimport {\n SchemaService,\n type RelationshipDef,\n type AttributeDef,\n} from '@mobx-data/schema';\nimport {\n Model,\n ManyArray,\n AsyncBelongsTo,\n AsyncHasMany,\n type RelationshipRef,\n type ModelStoreLike,\n type SaveOptions,\n} from '@mobx-data/model';\nimport type { CacheLike } from '../cache/types.js';\nimport {\n extractResponseHeaders,\n parseCacheTTLFromHeaders,\n} from '../cache/cache-utils.js';\nimport { IdentityMap } from './IdentityMap.js';\nimport {\n RecordArray,\n AdapterPopulatedRecordArray,\n} from './RecordArray.js';\n\n/** Options forwarded from the Store to adapter fetch methods. */\nexport interface AdapterFetchOptions {\n include?: string;\n adapterOptions?: Record<string, unknown>;\n}\n\n/** Minimal adapter interface the Store depends on. */\nexport interface AdapterLike {\n findRecord(\n store: Store,\n modelName: string,\n id: string,\n snapshot: unknown,\n options?: AdapterFetchOptions,\n ): Promise<unknown>;\n findAll(\n store: Store,\n modelName: string,\n sinceToken: string | null,\n snapshotArray: unknown,\n options?: AdapterFetchOptions,\n ): Promise<unknown>;\n findMany?(\n store: Store,\n modelName: string,\n ids: string[],\n snapshots: unknown,\n ): Promise<unknown>;\n query(\n store: Store,\n modelName: string,\n query: Record<string, unknown>,\n recordArray: AdapterPopulatedRecordArray,\n ): Promise<unknown>;\n queryRecord(\n store: Store,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown>;\n createRecord(\n store: Store,\n modelName: string,\n snapshot: unknown,\n ): Promise<unknown>;\n updateRecord(\n store: Store,\n modelName: string,\n snapshot: unknown,\n ): Promise<unknown>;\n patchRecord?(\n store: Store,\n modelName: string,\n snapshot: unknown,\n ): Promise<unknown>;\n deleteRecord(\n store: Store,\n modelName: string,\n snapshot: unknown,\n ): Promise<unknown>;\n /** When `true` the store coalesces multiple `findRecord` calls into one `findMany`. */\n coalesceFindRequests?: boolean;\n}\n\n/** Minimal serializer interface the Store depends on. */\nexport interface SerializerLike {\n normalize(\n store: Store,\n modelClass: unknown,\n payload: unknown,\n prop?: string,\n ): unknown;\n normalizeResponse(\n store: Store,\n modelClass: unknown,\n payload: unknown,\n id: string | null,\n requestType: string,\n ): unknown;\n serialize(snapshot: unknown, options?: Record<string, unknown>): unknown;\n extractErrors?(\n store: Store,\n modelClass: unknown,\n payload: unknown,\n id: string | null,\n ): Record<string, string[]>;\n}\n\n/** Options for `findRecord` and `findAll`. */\nexport interface FindOptions {\n /** When `true`, bypass the cache and always hit the network. */\n reload?: boolean;\n /** When `true`, return the cached value and refetch in the background. */\n backgroundReload?: boolean;\n /** Adapter-specific options forwarded to the adapter method. */\n adapterOptions?: Record<string, unknown>;\n /** Comma-separated relationship paths to include (e.g. `'author,comments'`). */\n include?: string;\n}\n\n/** Normalized resource shape consumed internally by the store. */\nexport interface NormalizedResource {\n type: string;\n id: string | null;\n attributes?: Record<string, unknown>;\n relationships?: Record<string, RelationshipRef>;\n}\n\n/** Normalized document containing primary data and optional side-loaded records. */\nexport interface NormalizedDocument {\n data: NormalizedResource | NormalizedResource[] | null;\n included?: NormalizedResource[];\n meta?: Record<string, unknown>;\n links?: Record<string, string>;\n}\n\n/** Internal snapshot interface created and consumed by the store. */\ninterface Snapshot {\n id: string | null;\n modelName: string;\n record: Model;\n attr(key: string): unknown;\n belongsTo(key: string, options?: { id?: boolean }): unknown;\n hasMany(key: string, options?: { ids?: boolean }): unknown;\n changedAttributes(): Record<string, [unknown, unknown]>;\n eachAttribute(fn: (key: string, meta: AttributeDef) => void): void;\n eachRelationship(fn: (key: string, meta: RelationshipDef) => void): void;\n}\n\n@singleton()\n@injectable()\nexport class Store implements ModelStoreLike {\n static refEquals(\n a: { type: string; id: string },\n b: { type: string; id: string },\n ): boolean {\n return a.id === b.id && a.type === b.type;\n }\n\n /** Schema registry used to look up model classes and their metadata. */\n readonly schema: SchemaService;\n\n /** Two-level identity map: `modelName → id → record`. */\n readonly identityMap: IdentityMap = new IdentityMap();\n\n private adapters: Map<string, AdapterLike> = new Map();\n\n private serializers: Map<string, SerializerLike> = new Map();\n\n /** Tracks unsaved (new) records by model name. */\n private newRecords: Map<string, Set<Model>> = new Map();\n\n /** Reverse index: record → modelName for O(1) untrackNewRecord. */\n private newRecordTypes: WeakMap<Model, string> = new WeakMap();\n\n /** Per-record cache of relationship proxy objects (ManyArray / AsyncBelongsTo / AsyncHasMany). */\n private relationshipCache: WeakMap<\n Model,\n Map<string, ManyArray | AsyncBelongsTo | AsyncHasMany>\n > = new WeakMap();\n\n /** Tracks new records that have been appended to a hasMany but not yet saved. */\n private pendingMembers: WeakMap<Model, Map<string, Set<Model>>> = new WeakMap();\n\n /** Optional persistent cache layer (e.g. IndexedDB). */\n private _cache: CacheLike | null = null;\n\n constructor(@inject(SchemaService) schema: SchemaService) {\n this.schema = schema;\n }\n\n // --- registration ---\n\n /** Registers an adapter for a given model name (or `'application'` as a fallback). */\n registerAdapter(modelName: string, adapter: AdapterLike): void {\n this.adapters.set(modelName, adapter);\n }\n\n /** Registers a serializer for a given model name (or `'application'` as a fallback). */\n registerSerializer(modelName: string, serializer: SerializerLike): void {\n this.serializers.set(modelName, serializer);\n }\n\n /** Registers a persistent cache layer (e.g. IndexedDB) for offline-first reads. */\n registerCache(cache: CacheLike): void {\n this._cache = cache;\n }\n\n /**\n * Returns the adapter for `modelName`, falling back to `'application'`.\n * @throws when no adapter is registered.\n */\n adapterFor(modelName: string): AdapterLike {\n const adapter = this.adapters.get(modelName) ?? this.adapters.get('application');\n if (!adapter) {\n throw new Error(`No adapter registered for \"${modelName}\"`);\n }\n return adapter;\n }\n\n /**\n * Returns the serializer for `modelName`, falling back to `'application'`.\n * @throws when no serializer is registered.\n */\n serializerFor(modelName: string): SerializerLike {\n const serializer = this.serializers.get(modelName)\n ?? this.serializers.get('application');\n if (!serializer) {\n throw new Error(`No serializer registered for \"${modelName}\"`);\n }\n return serializer;\n }\n\n // --- creating ---\n\n /**\n * Creates a new (unsaved) record of the given type with optional initial data.\n * The record is tracked in `newRecords` until it is saved or rolled back.\n *\n * @throws when `modelName` has not been registered with `SchemaService`.\n */\n createRecord<T extends Model = Model>(\n modelName: string,\n data: Record<string, unknown> = {},\n ): T {\n if (!this.schema.doesTypeExist(modelName)) {\n throw new Error(`Unknown model type: \"${modelName}\"`);\n }\n const Klass = this.schema.modelFor(modelName) as unknown as new (\n opts: { id: null; data: Record<string, unknown>; store: Store },\n ) => Model;\n const record = new Klass({ id: null, data, store: this });\n this.trackNewRecord(modelName, record);\n return record as T;\n }\n\n private trackNewRecord(modelName: string, record: Model): void {\n let set = this.newRecords.get(modelName);\n if (!set) {\n set = new Set();\n this.newRecords.set(modelName, set);\n }\n set.add(record);\n this.newRecordTypes.set(record, modelName);\n }\n\n private untrackNewRecord(record: Model): void {\n const modelName = this.newRecordTypes.get(record);\n if (modelName) {\n this.newRecords.get(modelName)?.delete(record);\n this.newRecordTypes.delete(record);\n }\n }\n\n // --- peeking ---\n\n /**\n * Synchronously returns a record from the identity map, or `null` when not\n * found. Does not trigger a network request.\n */\n peekRecord<T extends Model = Model>(modelName: string, id: string): T | null {\n const key = id === null || id === undefined ? null : String(id);\n if (key === null) {\n return null;\n }\n return (this.identityMap.get(modelName, key) as T | null) ?? null;\n }\n\n /**\n * Returns a live `RecordArray` backed by the identity map for `modelName`.\n * New (unsaved) records are included at the end.\n * Does not trigger a network request.\n */\n peekAll<T extends Model = Model>(modelName: string): RecordArray<T> {\n return new RecordArray<T>({\n modelName,\n source: () => {\n const persisted = this.identityMap.all(modelName) as T[];\n const newRecordsForType = this.newRecords.get(modelName);\n if (!newRecordsForType || newRecordsForType.size === 0) {\n return persisted;\n }\n return [...persisted, ...(newRecordsForType as unknown as Set<T>)];\n },\n });\n }\n\n // --- push / normalize ---\n\n /**\n * Pushes a normalized document into the identity map.\n * Side-loaded (`included`) records are pushed first.\n *\n * @returns The primary record(s), or `null` for empty payloads.\n */\n push(doc: unknown): Model | Model[] | null {\n const document = doc as NormalizedDocument;\n if (document.included) {\n for (const resource of document.included) {\n this.pushResource(resource);\n }\n }\n if (document.data === null || document.data === undefined) {\n return null;\n }\n if (Array.isArray(document.data)) {\n return document.data.map((resource) => this.pushResource(resource));\n }\n return this.pushResource(document.data);\n }\n\n /**\n * Normalizes a raw payload via the registered serializer and pushes the\n * result. `modelName` is optional; when omitted the payload is pushed\n * directly without normalization.\n */\n pushPayload(modelNameOrPayload: string | unknown, payload?: unknown): void {\n let modelName: string | null;\n let body: unknown;\n if (typeof modelNameOrPayload === 'string') {\n modelName = modelNameOrPayload;\n body = payload;\n } else {\n modelName = null;\n body = modelNameOrPayload;\n }\n const normalized = modelName\n ? this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n body,\n null,\n 'pushPayload',\n )\n : body;\n this.push(normalized);\n }\n\n /**\n * Normalizes a raw payload for `modelName` via the registered serializer\n * and returns the `NormalizedDocument` without pushing it.\n */\n normalize(modelName: string, payload: unknown): NormalizedDocument {\n return this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n payload,\n null,\n 'normalize',\n ) as NormalizedDocument;\n }\n\n /**\n * Inserts or merges a single normalized resource into the identity map.\n * - Existing record → calls `_applyServerData` to merge attributes and\n * relationships in place (preserving the live reference).\n * - New record → instantiates via `Model.push` and sets it in the map.\n *\n * @throws when `type` has not been registered or `id` is `null`.\n */\n private pushResource(resource: NormalizedResource): Model {\n const { type, id } = resource;\n if (!this.schema.doesTypeExist(type)) {\n throw new Error(`Unknown model type: \"${type}\"`);\n }\n if (id === null) {\n throw new Error(`Cannot push a resource of type \"${type}\" without an id`);\n }\n const existing = this.identityMap.get(type, id);\n if (existing) {\n runInAction(() => {\n (existing as unknown as {\n _applyServerData(\n id: string | null,\n data: Record<string, unknown>,\n relationships?: Record<string, RelationshipRef>,\n ): void;\n })._applyServerData(null, resource.attributes ?? {}, resource.relationships);\n });\n this.trackInverseForResource(existing, resource);\n return existing;\n }\n const Klass = this.schema.modelFor(type) as unknown as new (\n opts: {\n id: string;\n data: Record<string, unknown>;\n relationships?: Record<string, RelationshipRef>;\n store: Store;\n },\n ) => Model;\n const record = Model.push.call(Klass as unknown as typeof Model, {\n id,\n data: resource.attributes ?? {},\n relationships: resource.relationships,\n store: this,\n }) as Model;\n this.identityMap.set(type, id, record);\n this.trackInverseForResource(record, resource);\n return record;\n }\n\n /**\n * After pushing a resource, updates the inverse side of every declared\n * inverse relationship so both sides stay consistent.\n */\n private trackInverseForResource(record: Model, resource: NormalizedResource): void {\n if (!resource.relationships) {\n return;\n }\n for (const [name, ref] of Object.entries(resource.relationships)) {\n const meta = this.schema.relationshipsDefinitionFor(record.modelName).get(name);\n if (!meta) {\n continue;\n }\n if (!meta.options.inverse) {\n continue;\n }\n if (!ref.data) {\n continue;\n }\n const items = Array.isArray(ref.data) ? ref.data : [ref.data];\n for (const item of items) {\n this.addInverse(item.type, item.id, meta.options.inverse, record);\n }\n }\n }\n\n /**\n * Adds `inverseRecord` to the inverse relationship on `targetType:targetId`.\n * No-ops when the target record is not in the identity map.\n */\n private addInverse(\n targetType: string,\n targetId: string,\n inverseName: string,\n inverseRecord: Model,\n ): void {\n const target = this.identityMap.get(targetType, targetId);\n if (!target) {\n return;\n }\n const targetRelationships = this.schema.relationshipsDefinitionFor(targetType);\n const inverseMeta = targetRelationships.get(inverseName);\n if (!inverseMeta) {\n return;\n }\n const existing = (target as unknown as {\n _getRelationshipRef(name: string): RelationshipRef | null;\n })._getRelationshipRef(inverseName);\n const inverseEntry = { type: inverseRecord.modelName, id: inverseRecord.id! };\n runInAction(() => {\n if (inverseMeta.kind === 'hasMany') {\n const currentData = existing?.data && Array.isArray(existing.data)\n ? existing.data : [];\n if (!currentData.some((reference) => Store.refEquals(reference, inverseEntry))) {\n (target as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(inverseName, { data: [...currentData, inverseEntry] });\n }\n } else {\n (target as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(inverseName, { data: inverseEntry });\n }\n });\n }\n\n /**\n * Removes `inverseRecord` from the inverse relationship on `targetType:targetId`.\n * No-ops when the target record is not in the identity map.\n */\n private removeInverse(\n targetType: string,\n targetId: string,\n inverseName: string,\n inverseRecord: Model,\n ): void {\n const target = this.identityMap.get(targetType, targetId);\n if (!target) {\n return;\n }\n const targetRelationships = this.schema.relationshipsDefinitionFor(targetType);\n const inverseMeta = targetRelationships.get(inverseName);\n if (!inverseMeta) {\n return;\n }\n const existing = (target as unknown as {\n _getRelationshipRef(name: string): RelationshipRef | null;\n })._getRelationshipRef(inverseName);\n runInAction(() => {\n if (inverseMeta.kind === 'hasMany') {\n const currentData = existing?.data && Array.isArray(existing.data)\n ? existing.data : [];\n const items = currentData.filter((reference) => !(\n reference.id === inverseRecord.id\n && reference.type === inverseRecord.modelName\n ));\n (target as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(inverseName, { data: items });\n } else {\n (target as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(inverseName, { data: null });\n }\n });\n }\n\n // --- unload ---\n\n /**\n * Removes a record from the identity map and clears its relationship cache.\n * Called by `record.unloadRecord()` and internally after `deleteRecord`.\n */\n unloadRecord(record: Model): void {\n if (record.id !== null) {\n this.identityMap.delete(record.modelName, record.id);\n }\n this.untrackNewRecord(record);\n this.relationshipCache.delete(record);\n }\n\n /**\n * Unloads all records for `modelName`, or all records across all types when\n * `modelName` is omitted.\n */\n unloadAll(modelName?: string): void {\n if (modelName) {\n for (const record of this.identityMap.all(modelName)) {\n this.relationshipCache.delete(record);\n }\n this.identityMap.clear(modelName);\n this.newRecords.get(modelName)?.clear();\n } else {\n this.identityMap.clear();\n this.newRecords.clear();\n }\n }\n\n // --- find ---\n\n /**\n * Finds a single record by id. Returns the cached record immediately when\n * `options.reload` is not set; otherwise re-fetches.\n *\n * When the adapter has `coalesceFindRequests: true` and `findMany` is\n * implemented, multiple concurrent `findRecord` calls for the same type\n * are batched into a single `findMany` network request.\n */\n async findRecord<T extends Model = Model>(\n modelName: string,\n id: string,\n options: FindOptions = {},\n ): Promise<T> {\n const cached = this.peekRecord<T>(modelName, id);\n if (cached && !options.reload && !options.include) {\n return cached;\n }\n\n if (!options.reload && !options.include && this._cache) {\n const cacheEntry = await this._cache.get(modelName, id);\n if (cacheEntry) {\n const record = this.push({\n data: {\n type: cacheEntry.modelName,\n id: cacheEntry.id,\n attributes: cacheEntry.attributes,\n relationships: cacheEntry.relationships,\n },\n });\n return record as T;\n }\n }\n\n const adapter = this.adapterFor(modelName);\n\n if (adapter.coalesceFindRequests && adapter.findMany && !options.include) {\n return this.scheduleCoalescedFind(modelName, id) as Promise<T>;\n }\n\n const snapshot = cached ? this.createSnapshot(cached) : this.createEmptySnapshot(modelName, id);\n const adapterOptions: AdapterFetchOptions | undefined = options.include\n ? { include: options.include, adapterOptions: options.adapterOptions }\n : options.adapterOptions ? { adapterOptions: options.adapterOptions } : undefined;\n const response = await adapter.findRecord(this, modelName, id, snapshot, adapterOptions);\n const responseHeaders = extractResponseHeaders(response);\n const doc = this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n response,\n id,\n 'findRecord',\n ) as NormalizedDocument;\n const record = this.push(doc);\n\n if (this._cache) {\n const ttl = responseHeaders\n ? parseCacheTTLFromHeaders(responseHeaders)\n : undefined;\n if (ttl !== 0) {\n this.cacheNormalizedDocument(doc, ttl);\n }\n }\n\n return record as T;\n }\n\n /**\n * Fetches all records of `modelName` from the server and returns a\n * `RecordArray` backed by the identity map.\n */\n async findAll<T extends Model = Model>(\n modelName: string,\n options: FindOptions = {},\n ): Promise<RecordArray<T>> {\n const adapter = this.adapterFor(modelName);\n const adapterOptions: AdapterFetchOptions | undefined = options.include\n ? { include: options.include, adapterOptions: options.adapterOptions }\n : options.adapterOptions ? { adapterOptions: options.adapterOptions } : undefined;\n const response = await adapter.findAll(this, modelName, null, [], adapterOptions);\n const responseHeaders = extractResponseHeaders(response);\n const doc = this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n response,\n null,\n 'findAll',\n ) as NormalizedDocument;\n this.push(doc);\n\n if (this._cache) {\n const ttl = responseHeaders\n ? parseCacheTTLFromHeaders(responseHeaders)\n : undefined;\n if (ttl !== 0) {\n this.cacheNormalizedDocument(doc, ttl);\n }\n }\n\n return this.peekAll<T>(modelName);\n }\n\n /**\n * Executes an adapter query and returns an `AdapterPopulatedRecordArray`\n * whose `update()` method re-issues the same query.\n */\n async query<T extends Model = Model>(\n modelName: string,\n params: Record<string, unknown>,\n ): Promise<AdapterPopulatedRecordArray<T>> {\n const ids: string[] = [];\n const array = new AdapterPopulatedRecordArray<T>({\n modelName,\n query: params,\n source: () => ids\n .map((id) => this.peekRecord<T>(modelName, id))\n .filter((r): r is T => r !== null),\n update: async () => {\n await this.runQuery(modelName, params, array, ids);\n },\n });\n await this.runQuery(modelName, params, array, ids);\n return array;\n }\n\n private async runQuery<T extends Model>(\n modelName: string,\n params: Record<string, unknown>,\n array: AdapterPopulatedRecordArray<T>,\n ids: string[],\n ): Promise<void> {\n const adapter = this.adapterFor(modelName);\n const response = await adapter.query(this, modelName, params, array);\n const doc = this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n response,\n null,\n 'query',\n ) as NormalizedDocument;\n this.push(doc);\n ids.length = 0;\n if (Array.isArray(doc.data)) {\n for (const resource of doc.data) {\n if (resource.id) {\n ids.push(resource.id);\n }\n }\n }\n if (doc.meta) {\n array._setMeta(doc.meta);\n }\n if (doc.links) {\n array._setLinks(doc.links);\n }\n }\n\n /**\n * Executes an adapter query that returns at most one record.\n * Returns `null` when the adapter returns an empty payload.\n */\n async queryRecord<T extends Model = Model>(\n modelName: string,\n params: Record<string, unknown>,\n ): Promise<T | null> {\n const adapter = this.adapterFor(modelName);\n const response = await adapter.queryRecord(this, modelName, params);\n const doc = this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n response,\n null,\n 'queryRecord',\n ) as NormalizedDocument;\n const result = this.push(doc);\n if (Array.isArray(result)) {\n return (result[0] ?? null) as T | null;\n }\n return (result as T | null) ?? null;\n }\n\n // --- save / delete / reload from Model ---\n\n /**\n * Persists a record to the server.\n * - New records → `adapter.createRecord` (POST)\n * - Existing dirty records → `adapter.updateRecord` (PUT) by default\n * - With `{ patch: true }` → `adapter.patchRecord` (PATCH, partial payload)\n *\n * After the response is received the server data is applied back to the\n * record via `_applyServerData` so it transitions to `saved`.\n */\n async saveRecord<T extends Model>(record: T, options: SaveOptions = {}): Promise<T> {\n const adapter = this.adapterFor(record.modelName);\n const snapshot = this.createSnapshot(record);\n const { isNew } = record;\n let response: unknown;\n if (isNew) {\n response = await adapter.createRecord(this, record.modelName, snapshot);\n } else if (options.patch && adapter.patchRecord) {\n response = await adapter.patchRecord(this, record.modelName, snapshot);\n } else {\n response = await adapter.updateRecord(this, record.modelName, snapshot);\n }\n const doc = this.serializerFor(record.modelName).normalizeResponse(\n this,\n this.schema.modelFor(record.modelName),\n response,\n record.id,\n isNew ? 'createRecord' : 'updateRecord',\n ) as NormalizedDocument;\n const data = doc.data as NormalizedResource | null;\n if (data) {\n const newId = data.id ?? record.id;\n runInAction(() => {\n (record as unknown as {\n _applyServerData(\n id: string | null,\n data: Record<string, unknown>,\n relationships?: Record<string, RelationshipRef>,\n ): void;\n })._applyServerData(newId, data.attributes ?? {}, data.relationships);\n });\n if (isNew && newId) {\n this.untrackNewRecord(record);\n this.identityMap.set(record.modelName, newId, record);\n }\n }\n if (doc.included) {\n for (const resource of doc.included) {\n this.pushResource(resource);\n }\n }\n\n if (this._cache && record.id) {\n const internal = record as unknown as {\n _data: Record<string, unknown>;\n _relationships: Map<string, RelationshipRef>;\n };\n const relationships: Record<string, RelationshipRef> = {};\n for (const [name, ref] of internal._relationships) {\n relationships[name] = ref;\n }\n this._cache.set(record.modelName, record.id, { ...internal._data }, {\n relationships: Object.keys(relationships).length > 0\n ? relationships : undefined,\n });\n }\n\n return record;\n }\n\n /**\n * Issues a DELETE request and unloads the record from the identity map.\n */\n async deleteRecord<T extends Model>(record: T): Promise<T> {\n const adapter = this.adapterFor(record.modelName);\n const snapshot = this.createSnapshot(record);\n await adapter.deleteRecord(this, record.modelName, snapshot);\n if (this._cache && record.id) {\n this._cache.invalidate(record.modelName, record.id);\n }\n this.unloadRecord(record);\n return record;\n }\n\n /**\n * Re-fetches a record from the server and merges the response into the\n * existing instance.\n */\n async reloadRecord<T extends Model>(record: T): Promise<T> {\n if (!record.id) {\n throw new Error('Cannot reload a record without an id');\n }\n const adapter = this.adapterFor(record.modelName);\n const snapshot = this.createSnapshot(record);\n const response = await adapter.findRecord(this, record.modelName, record.id, snapshot);\n const doc = this.serializerFor(record.modelName).normalizeResponse(\n this,\n this.schema.modelFor(record.modelName),\n response,\n record.id,\n 'findRecord',\n ) as NormalizedDocument;\n this.push(doc);\n return record;\n }\n\n // --- snapshot ---\n\n /**\n * Creates a `Snapshot` for a live record.\n * The snapshot reads directly from the record's internal state so it\n * reflects the current (possibly dirty) values.\n */\n createSnapshot(record: Model): Snapshot {\n const { modelName } = record;\n const attributes = this.schema.attributesDefinitionFor(modelName);\n const relationships = this.schema.relationshipsDefinitionFor(modelName);\n const internal = record as unknown as {\n _data: Record<string, unknown>;\n _getRelationshipRef(name: string): RelationshipRef | null;\n changedAttributes(): Record<string, [unknown, unknown]>;\n };\n return {\n id: record.id,\n modelName,\n record,\n attr: (key) => internal._data[key],\n belongsTo: (key, options) => {\n const ref = internal._getRelationshipRef(key);\n if (!ref?.data || Array.isArray(ref.data)) {\n return null;\n }\n if (options?.id) {\n return ref.data.id;\n }\n return this.peekRecord(ref.data.type, ref.data.id);\n },\n hasMany: (key, options) => {\n const ref = internal._getRelationshipRef(key);\n const items: Array<{ type: string; id: string }> = ref?.data\n && Array.isArray(ref.data) ? ref.data : [];\n if (options?.ids) {\n return items.map((item) => item.id);\n }\n return items\n .map((item) => this.peekRecord(item.type, item.id))\n .filter((resolvedRecord): resolvedRecord is Model => resolvedRecord !== null);\n },\n changedAttributes: () => internal.changedAttributes(),\n eachAttribute: (callback) => {\n for (const [key, meta] of attributes) {\n callback(key, meta);\n }\n },\n eachRelationship: (callback) => {\n for (const [key, meta] of relationships) {\n callback(key, meta);\n }\n },\n };\n }\n\n /**\n * Creates a placeholder `Snapshot` for a record that is not yet in the\n * identity map (used when fetching a record that isn't cached).\n */\n private createEmptySnapshot(modelName: string, id: string): Snapshot {\n const attributes = this.schema.attributesDefinitionFor(modelName);\n const relationships = this.schema.relationshipsDefinitionFor(modelName);\n return {\n id,\n modelName,\n record: null as unknown as Model,\n attr: () => undefined,\n belongsTo: () => null,\n hasMany: () => [],\n changedAttributes: () => ({}),\n eachAttribute: (callback) => {\n for (const [key, meta] of attributes) {\n callback(key, meta);\n }\n },\n eachRelationship: (callback) => {\n for (const [key, meta] of relationships) {\n callback(key, meta);\n }\n },\n };\n }\n\n // --- relationship resolution (called by Model) ---\n\n private getRelationshipCache(\n record: Model,\n name: string,\n ): ManyArray | AsyncBelongsTo | AsyncHasMany | undefined {\n return this.relationshipCache.get(record)?.get(name);\n }\n\n private setRelationshipCache(\n record: Model,\n name: string,\n value: ManyArray | AsyncBelongsTo | AsyncHasMany,\n ): void {\n let m = this.relationshipCache.get(record);\n if (!m) {\n m = new Map();\n this.relationshipCache.set(record, m);\n }\n m.set(name, value);\n }\n\n /**\n * Called by the `Model` relationship getter to resolve a relationship.\n *\n * - **Async** `belongsTo` → returns an `AsyncBelongsTo` wrapper.\n * - **Async** `hasMany` → returns an `AsyncHasMany` wrapper.\n * - **Sync** `belongsTo` → peeks the related record from the identity map.\n * - **Sync** `hasMany` → returns a `ManyArray` backed by the store.\n *\n * Results are cached per record + name so the same proxy is returned on\n * repeated accesses (important for MobX observability).\n */\n resolveRelationship(record: Model, name: string, meta: RelationshipDef): unknown {\n const isAsync = meta.options.async === true;\n const cached = this.getRelationshipCache(record, name);\n if (cached) {\n return cached;\n }\n const hostWithStore = {\n parent: record,\n name,\n meta,\n store: this as unknown as never,\n };\n\n if (isAsync) {\n if (meta.kind === 'belongsTo') {\n const wrapper = new AsyncBelongsTo(hostWithStore as never);\n this.setRelationshipCache(record, name, wrapper);\n return wrapper;\n }\n const wrapper = new AsyncHasMany(hostWithStore as never);\n this.setRelationshipCache(record, name, wrapper);\n return wrapper;\n }\n\n if (meta.kind === 'belongsTo') {\n const ref = (record as unknown as {\n _getRelationshipRef(name: string): RelationshipRef | null;\n })._getRelationshipRef(name);\n if (!ref?.data || Array.isArray(ref.data)) {\n return null;\n }\n return this.peekRecord(ref.data.type, ref.data.id);\n }\n const arr = new ManyArray(hostWithStore as never);\n this.setRelationshipCache(record, name, arr);\n return arr;\n }\n\n /**\n * Called by the `Model` `belongsTo` setter to update a relationship ref\n * and keep its inverse in sync.\n */\n setRelationshipValue(\n record: Model,\n name: string,\n meta: RelationshipDef,\n value: unknown,\n ): void {\n if (meta.kind !== 'belongsTo') {\n return;\n }\n const ref = (record as unknown as {\n _getRelationshipRef(name: string): RelationshipRef | null;\n })._getRelationshipRef(name);\n const prev = ref?.data && !Array.isArray(ref.data) ? ref.data : null;\n\n if (value === null || value === undefined) {\n runInAction(() => {\n (record as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(name, { data: null });\n });\n if (prev && meta.options.inverse) {\n this.removeInverse(prev.type, prev.id, meta.options.inverse, record);\n }\n return;\n }\n\n const target = value as Model;\n const newRef = { type: target.modelName, id: target.id! };\n runInAction(() => {\n (record as unknown as {\n _setRelationshipRef(name: string, ref: RelationshipRef): void;\n })._setRelationshipRef(name, { data: newRef });\n });\n\n if (meta.options.inverse) {\n if (prev && !Store.refEquals(prev, newRef)) {\n this.removeInverse(prev.type, prev.id, meta.options.inverse, record);\n }\n this.addInverse(newRef.type, newRef.id, meta.options.inverse, record);\n }\n }\n\n // --- hooks used by ManyArray ---\n\n /** Returns the raw relationship ref stored on `record` for `name`. */\n _getRelationshipRefFor(record: Model, name: string): RelationshipRef | null {\n return (record as unknown as {\n _getRelationshipRef(n: string): RelationshipRef | null;\n })._getRelationshipRef(name);\n }\n\n /** Returns any pending (unsaved) members for a `hasMany` relationship. */\n _getPendingMembers(record: Model, name: string): Iterable<Model> {\n return this.pendingMembers.get(record)?.get(name) ?? [];\n }\n\n private addPendingMember(record: Model, name: string, value: Model): void {\n let byName = this.pendingMembers.get(record);\n if (!byName) {\n byName = new Map();\n this.pendingMembers.set(record, byName);\n }\n let set = byName.get(name);\n if (!set) {\n set = observable.set<Model>();\n byName.set(name, set);\n }\n set.add(value);\n }\n\n private removePendingMember(record: Model, name: string, value: Model): void {\n this.pendingMembers.get(record)?.get(name)?.delete(value);\n }\n\n /**\n * Appends `value` to the `hasMany` relationship ref on `record` and syncs\n * the inverse. Unsaved records (`value.id === null`) are tracked as\n * \"pending members\" until they are persisted.\n */\n _hasManyAppend(\n record: Model,\n name: string,\n meta: RelationshipDef,\n value: Model,\n ): void {\n if (value.id === null) {\n this.addPendingMember(record, name, value);\n if (meta.options.inverse) {\n const inverseMeta = this.schema\n .relationshipsDefinitionFor(value.modelName)\n .get(meta.options.inverse);\n if (inverseMeta?.kind === 'belongsTo') {\n runInAction(() => {\n (value as unknown as {\n _setRelationshipRef(n: string, r: RelationshipRef): void;\n })._setRelationshipRef(meta.options.inverse!, {\n data: { type: record.modelName, id: record.id! },\n });\n });\n }\n }\n return;\n }\n const ref = this._getRelationshipRefFor(record, name);\n const currentData = ref?.data && Array.isArray(ref.data) ? ref.data : [];\n const entry = { type: value.modelName, id: value.id };\n if (!currentData.some((reference) => Store.refEquals(reference, entry))) {\n runInAction(() => {\n (record as unknown as {\n _setRelationshipRef(n: string, r: RelationshipRef): void;\n })._setRelationshipRef(name, { data: [...currentData, entry] });\n });\n }\n if (meta.options.inverse) {\n this.addInverse(value.modelName, value.id, meta.options.inverse, record);\n }\n }\n\n /**\n * Removes `value` from the `hasMany` relationship ref on `record` and syncs\n * the inverse. Pending members are removed from the pending set.\n */\n _hasManyRemove(\n record: Model,\n name: string,\n meta: RelationshipDef,\n value: Model,\n ): void {\n if (value.id === null) {\n this.removePendingMember(record, name, value);\n return;\n }\n const ref = this._getRelationshipRefFor(record, name);\n const currentData = ref?.data && Array.isArray(ref.data) ? ref.data : [];\n const filtered = currentData.filter(\n (reference) => !(reference.id === value.id && reference.type === value.modelName),\n );\n runInAction(() => {\n (record as unknown as {\n _setRelationshipRef(n: string, r: RelationshipRef): void;\n })._setRelationshipRef(name, { data: filtered });\n });\n if (meta.options.inverse) {\n this.removeInverse(value.modelName, value.id, meta.options.inverse, record);\n }\n }\n\n // --- persistent cache helpers ---\n\n private cacheNormalizedDocument(\n doc: NormalizedDocument,\n ttl?: number,\n ): void {\n if (!this._cache) {\n return;\n }\n const resources: NormalizedResource[] = [];\n if (doc.data) {\n if (Array.isArray(doc.data)) {\n resources.push(...doc.data);\n } else {\n resources.push(doc.data);\n }\n }\n if (doc.included) {\n resources.push(...doc.included);\n }\n for (const resource of resources) {\n if (resource.id) {\n this._cache.set(resource.type, resource.id, resource.attributes ?? {}, {\n relationships: resource.relationships,\n ttl,\n });\n }\n }\n }\n\n // --- coalesceFindRequests ---\n\n private coalescePending: Map<string, Map<string, {\n resolve: (record: Model) => void;\n reject: (error: unknown) => void;\n }[]>> = new Map();\n\n private coalesceScheduled: Set<string> = new Set();\n\n private scheduleCoalescedFind(modelName: string, id: string): Promise<Model> {\n return new Promise((resolve, reject) => {\n let byId = this.coalescePending.get(modelName);\n if (!byId) {\n byId = new Map();\n this.coalescePending.set(modelName, byId);\n }\n let callbacks = byId.get(id);\n if (!callbacks) {\n callbacks = [];\n byId.set(id, callbacks);\n }\n callbacks.push({ resolve, reject });\n\n if (!this.coalesceScheduled.has(modelName)) {\n this.coalesceScheduled.add(modelName);\n queueMicrotask(() => this.flushCoalescedFind(modelName));\n }\n });\n }\n\n private async flushCoalescedFind(modelName: string): Promise<void> {\n this.coalesceScheduled.delete(modelName);\n const byId = this.coalescePending.get(modelName);\n if (!byId || byId.size === 0) {\n return;\n }\n const pendingEntries = new Map(byId);\n byId.clear();\n\n const ids = Array.from(pendingEntries.keys());\n const adapter = this.adapterFor(modelName);\n\n try {\n const snapshots = ids.map((id) => {\n const cached = this.peekRecord(modelName, id);\n return cached\n ? this.createSnapshot(cached)\n : this.createEmptySnapshot(modelName, id);\n });\n const response = await adapter.findMany!(this, modelName, ids, snapshots);\n const doc = this.serializerFor(modelName).normalizeResponse(\n this,\n this.schema.modelFor(modelName),\n response,\n null,\n 'findMany',\n ) as NormalizedDocument;\n this.push(doc);\n\n for (const id of ids) {\n const record = this.peekRecord(modelName, id);\n const callbacks = pendingEntries.get(id);\n if (callbacks) {\n for (const callback of callbacks) {\n if (record) {\n callback.resolve(record);\n } else {\n callback.reject(new Error(`Record not found after findMany: ${modelName}:${id}`));\n }\n }\n }\n }\n } catch (error) {\n for (const callbacks of pendingEntries.values()) {\n for (const callback of callbacks) {\n callback.reject(error);\n }\n }\n }\n }\n\n // --- liveQuery ---\n\n /**\n * Returns a reactive `RecordArray` that auto-updates whenever records matching\n * the predicate are added, removed, or mutated in the identity map.\n *\n * The underlying computed uses `keepAlive: true` so it remains cached even\n * without active MobX observers — useful for long-lived filtered views.\n *\n * @param modelName - The registered model type to query.\n * @param predicate - Filter function applied to each record of `modelName`.\n * @returns A live `RecordArray` containing only records that satisfy `predicate`.\n */\n liveQuery<T extends Model = Model>(\n modelName: string,\n predicate: (record: T) => boolean,\n ): RecordArray<T> {\n return new RecordArray<T>({\n modelName,\n keepAlive: true,\n source: () => {\n const all = this.identityMap.all(modelName) as T[];\n const newRecordsForType = this.newRecords.get(modelName);\n const combined = newRecordsForType && newRecordsForType.size > 0\n ? [...all, ...(newRecordsForType as unknown as Set<T>)]\n : all;\n return combined.filter(predicate);\n },\n });\n }\n\n // --- optimisticUpdate ---\n\n /**\n * Applies attribute changes to a record immediately (optimistically), then\n * executes `persistFn`. If `persistFn` throws, the record is automatically\n * rolled back to its state before the optimistic update.\n *\n * @param record - The record to update optimistically.\n * @param optimisticAttributes - Attributes to apply before persistence.\n * @param persistFn - Async function that persists the change (e.g. `record.save()`).\n * @returns The record on success.\n * @throws Re-throws the error from `persistFn` after rollback.\n */\n async optimisticUpdate<T extends Model>(\n record: T,\n optimisticAttributes: Partial<Record<string, unknown>>,\n persistFn: () => Promise<unknown>,\n ): Promise<T> {\n const internal = record as unknown as {\n _data: Record<string, unknown>;\n _savedData: Record<string, unknown>;\n };\n const backup = { ...internal._data };\n\n runInAction(() => {\n Object.assign(internal._data, optimisticAttributes);\n });\n\n try {\n await persistFn();\n return record;\n } catch (error) {\n runInAction(() => {\n for (const [key, value] of Object.entries(backup)) {\n internal._data[key] = value;\n }\n });\n throw error;\n }\n }\n\n // --- runInTransaction ---\n\n /**\n * Executes multiple store mutations as a single MobX action, guaranteeing\n * that observers (and therefore UI renders) react only once — after all\n * mutations have been applied.\n *\n * @param callback - Synchronous function containing one or more store mutations.\n */\n runInTransaction(callback: () => void): void {\n runInAction(callback);\n }\n\n // --- SSR: serialize / hydrate ---\n\n /**\n * Produces a JSON-serializable snapshot of all records in the identity map.\n * Designed for server-side rendering: serialize on the server, transfer as\n * JSON, then `hydrate()` on the client to restore the full store state\n * without network requests.\n *\n * @param options.exclude - Per-model-type list of attribute keys to omit\n * (e.g. `{ user: ['password', 'token'] }`) to prevent leaking sensitive\n * data in SSR payloads.\n * @returns A snapshot object safe to pass through `JSON.stringify`.\n */\n serialize(options: {\n exclude?: Record<string, string[]>;\n } = {}): { records: Record<string, Array<{ id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> }>> } {\n const records: Record<string, Array<{ id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> }>> = {};\n const allTypes = this.identityMap._buckets;\n for (const [modelName, bucket] of allTypes) {\n const excludeKeys = options.exclude?.[modelName];\n const items: Array<{ id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> }> = [];\n for (const [id, record] of bucket) {\n const internal = record as unknown as {\n _data: Record<string, unknown>;\n _relationships: Map<string, RelationshipRef>;\n };\n let attributes: Record<string, unknown>;\n if (excludeKeys && excludeKeys.length > 0) {\n attributes = {};\n for (const [key, value] of Object.entries(internal._data)) {\n if (!excludeKeys.includes(key)) {\n attributes[key] = value;\n }\n }\n } else {\n attributes = { ...internal._data };\n }\n const entry: { id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> } = {\n id,\n attributes,\n };\n if (internal._relationships && internal._relationships.size > 0) {\n const relationships: Record<string, RelationshipRef> = {};\n for (const [name, ref] of internal._relationships) {\n relationships[name] = ref;\n }\n entry.relationships = relationships;\n }\n items.push(entry);\n }\n if (items.length > 0) {\n records[modelName] = items;\n }\n }\n return { records };\n }\n\n /**\n * Restores records from a snapshot produced by `serialize()` into this store\n * instance. All records are pushed into the identity map in `loaded.saved`\n * state — no network requests are issued.\n *\n * @param snapshot - A snapshot object previously returned by `serialize()`.\n */\n hydrate(snapshot: { records: Record<string, Array<{ id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> }>> }): void {\n runInAction(() => {\n for (const [modelName, items] of Object.entries(snapshot.records)) {\n for (const item of items) {\n this.pushResource({\n type: modelName,\n id: item.id,\n attributes: item.attributes,\n relationships: item.relationships,\n });\n }\n }\n });\n }\n\n /**\n * Factory method that creates a new `Store` and immediately hydrates it from\n * the given snapshot. Convenience for SSR client-side bootstrap.\n *\n * @param schema - SchemaService with all model types registered.\n * @param snapshot - A snapshot object previously returned by `serialize()`.\n * @returns A fully populated `Store` instance ready for use.\n */\n static hydrate(\n schema: SchemaService,\n snapshot: { records: Record<string, Array<{ id: string; attributes: Record<string, unknown>; relationships?: Record<string, RelationshipRef> }>> },\n ): Store {\n const store = new Store(schema);\n store.hydrate(snapshot);\n return store;\n }\n}\n"],"names":["IdentityMap","makeObservable","observable","action","modelName","create","existing","id","record","_a","bucket","total","RecordArray","opts","computed","index","callback","predicate","AdapterPopulatedRecordArray","meta","links","Store","schema","a","b","adapter","serializer","cache","data","Klass","set","key","persisted","newRecordsForType","doc","document","resource","modelNameOrPayload","payload","body","normalized","type","runInAction","Model","name","ref","items","item","targetType","targetId","inverseName","inverseRecord","target","inverseMeta","inverseEntry","currentData","reference","options","cached","cacheEntry","snapshot","adapterOptions","response","responseHeaders","extractResponseHeaders","ttl","parseCacheTTLFromHeaders","params","ids","array","r","result","isNew","newId","internal","relationships","attributes","resolvedRecord","value","m","isAsync","hostWithStore","wrapper","AsyncBelongsTo","AsyncHasMany","arr","ManyArray","prev","newRef","byName","_b","entry","filtered","resources","resolve","reject","byId","callbacks","pendingEntries","snapshots","error","all","optimisticAttributes","persistFn","backup","records","allTypes","excludeKeys","store","__decorateClass","singleton","injectable","__decorateParam","SchemaService"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const r=Symbol("response-headers"),c=36e5;function o(e){const t=e["cache-control"];if(t){if(/no-store/i.test(t)||/no-cache/i.test(t))return 0;const s=/s-maxage=(\d+)/i.exec(t);if(s)return parseInt(s[1],10)*1e3;const a=/max-age=(\d+)/i.exec(t);if(a)return parseInt(a[1],10)*1e3}const n=e.expires;if(n){const s=new Date(n).getTime();if(!Number.isNaN(s))return Math.max(0,s-Date.now())}return c}function i(e){return e!==null&&typeof e=="object"?e[r]??null:null}function u(e,t){e!==null&&typeof e=="object"&&Object.defineProperty(e,r,{value:t,enumerable:!1,writable:!1,configurable:!1})}exports.RESPONSE_HEADERS=r;exports.attachResponseHeaders=u;exports.extractResponseHeaders=i;exports.parseCacheTTLFromHeaders=o;
|
|
2
|
-
//# sourceMappingURL=cache-utils-2lswvJ87.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-utils-2lswvJ87.cjs","sources":["../src/cache/types.ts","../src/cache/cache-utils.ts"],"sourcesContent":["import type { RelationshipRef } from '@mobx-data/model';\n\nexport const RESPONSE_HEADERS: unique symbol = Symbol('response-headers');\n\nexport interface CacheEntryData {\n modelName: string;\n id: string;\n attributes: Record<string, unknown>;\n relationships?: Record<string, RelationshipRef>;\n cachedAt: number;\n expiresAt: number;\n}\n\nexport interface IndexedDBCacheOptions {\n databaseName?: string;\n defaultTTL?: number;\n}\n\nexport interface CacheLike {\n get(modelName: string, id: string): Promise<CacheEntryData | null>;\n set(\n modelName: string,\n id: string,\n attributes: Record<string, unknown>,\n options?: {\n relationships?: Record<string, RelationshipRef>;\n ttl?: number;\n },\n ): Promise<void>;\n has(modelName: string, id: string): Promise<boolean>;\n invalidate(modelName: string, id: string): Promise<void>;\n invalidateAll(modelName?: string): Promise<void>;\n}\n","import { RESPONSE_HEADERS } from './types.js';\n\nconst DEFAULT_TTL = 3_600_000;\n\nexport function parseCacheTTLFromHeaders(headers: Record<string, string>): number {\n const cacheControl = headers['cache-control'];\n if (cacheControl) {\n if (/no-store/i.test(cacheControl) || /no-cache/i.test(cacheControl)) {\n return 0;\n }\n const sMaxAge = /s-maxage=(\\d+)/i.exec(cacheControl);\n if (sMaxAge) {\n return parseInt(sMaxAge[1]!, 10) * 1000;\n }\n const maxAge = /max-age=(\\d+)/i.exec(cacheControl);\n if (maxAge) {\n return parseInt(maxAge[1]!, 10) * 1000;\n }\n }\n\n const expires = headers['expires'];\n if (expires) {\n const expiresMilliseconds = new Date(expires).getTime();\n if (!Number.isNaN(expiresMilliseconds)) {\n return Math.max(0, expiresMilliseconds - Date.now());\n }\n }\n\n return DEFAULT_TTL;\n}\n\nexport function extractResponseHeaders(\n payload: unknown,\n): Record<string, string> | null {\n if (payload !== null && typeof payload === 'object') {\n return (\n (payload as Record<symbol, unknown>)[RESPONSE_HEADERS] as\n | Record<string, string>\n | undefined\n ) ?? null;\n }\n return null;\n}\n\nexport function attachResponseHeaders(\n payload: unknown,\n headers: Record<string, string>,\n): void {\n if (payload !== null && typeof payload === 'object') {\n Object.defineProperty(payload, RESPONSE_HEADERS, {\n value: headers,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n }\n}\n"],"names":["RESPONSE_HEADERS","DEFAULT_TTL","parseCacheTTLFromHeaders","headers","cacheControl","sMaxAge","maxAge","expires","expiresMilliseconds","extractResponseHeaders","payload","attachResponseHeaders"],"mappings":"aAEO,MAAMA,EAAkC,OAAO,kBAAkB,ECAlEC,EAAc,KAEb,SAASC,EAAyBC,EAAyC,CAChF,MAAMC,EAAeD,EAAQ,eAAe,EAC5C,GAAIC,EAAc,CAChB,GAAI,YAAY,KAAKA,CAAY,GAAK,YAAY,KAAKA,CAAY,EACjE,MAAO,GAET,MAAMC,EAAU,kBAAkB,KAAKD,CAAY,EACnD,GAAIC,EACF,OAAO,SAASA,EAAQ,CAAC,EAAI,EAAE,EAAI,IAErC,MAAMC,EAAS,iBAAiB,KAAKF,CAAY,EACjD,GAAIE,EACF,OAAO,SAASA,EAAO,CAAC,EAAI,EAAE,EAAI,GAEtC,CAEA,MAAMC,EAAUJ,EAAQ,QACxB,GAAII,EAAS,CACX,MAAMC,EAAsB,IAAI,KAAKD,CAAO,EAAE,QAAA,EAC9C,GAAI,CAAC,OAAO,MAAMC,CAAmB,EACnC,OAAO,KAAK,IAAI,EAAGA,EAAsB,KAAK,KAAK,CAEvD,CAEA,OAAOP,CACT,CAEO,SAASQ,EACdC,EAC+B,CAC/B,OAAIA,IAAY,MAAQ,OAAOA,GAAY,SAEtCA,EAAoCV,CAAgB,GAGlD,KAEA,IACT,CAEO,SAASW,EACdD,EACAP,EACM,CACFO,IAAY,MAAQ,OAAOA,GAAY,UACzC,OAAO,eAAeA,EAASV,EAAkB,CAC/C,MAAOG,EACP,WAAY,GACZ,SAAU,GACV,aAAc,EAAA,CACf,CAEL"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const a = Symbol("response-headers"), c = 36e5;
|
|
2
|
-
function o(e) {
|
|
3
|
-
const t = e["cache-control"];
|
|
4
|
-
if (t) {
|
|
5
|
-
if (/no-store/i.test(t) || /no-cache/i.test(t))
|
|
6
|
-
return 0;
|
|
7
|
-
const n = /s-maxage=(\d+)/i.exec(t);
|
|
8
|
-
if (n)
|
|
9
|
-
return parseInt(n[1], 10) * 1e3;
|
|
10
|
-
const r = /max-age=(\d+)/i.exec(t);
|
|
11
|
-
if (r)
|
|
12
|
-
return parseInt(r[1], 10) * 1e3;
|
|
13
|
-
}
|
|
14
|
-
const s = e.expires;
|
|
15
|
-
if (s) {
|
|
16
|
-
const n = new Date(s).getTime();
|
|
17
|
-
if (!Number.isNaN(n))
|
|
18
|
-
return Math.max(0, n - Date.now());
|
|
19
|
-
}
|
|
20
|
-
return c;
|
|
21
|
-
}
|
|
22
|
-
function i(e) {
|
|
23
|
-
return e !== null && typeof e == "object" ? e[a] ?? null : null;
|
|
24
|
-
}
|
|
25
|
-
function f(e, t) {
|
|
26
|
-
e !== null && typeof e == "object" && Object.defineProperty(e, a, {
|
|
27
|
-
value: t,
|
|
28
|
-
enumerable: !1,
|
|
29
|
-
writable: !1,
|
|
30
|
-
configurable: !1
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export {
|
|
34
|
-
a as R,
|
|
35
|
-
f as a,
|
|
36
|
-
i as e,
|
|
37
|
-
o as p
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=cache-utils-38Dqu4Qf.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-utils-38Dqu4Qf.js","sources":["../src/cache/types.ts","../src/cache/cache-utils.ts"],"sourcesContent":["import type { RelationshipRef } from '@mobx-data/model';\n\nexport const RESPONSE_HEADERS: unique symbol = Symbol('response-headers');\n\nexport interface CacheEntryData {\n modelName: string;\n id: string;\n attributes: Record<string, unknown>;\n relationships?: Record<string, RelationshipRef>;\n cachedAt: number;\n expiresAt: number;\n}\n\nexport interface IndexedDBCacheOptions {\n databaseName?: string;\n defaultTTL?: number;\n}\n\nexport interface CacheLike {\n get(modelName: string, id: string): Promise<CacheEntryData | null>;\n set(\n modelName: string,\n id: string,\n attributes: Record<string, unknown>,\n options?: {\n relationships?: Record<string, RelationshipRef>;\n ttl?: number;\n },\n ): Promise<void>;\n has(modelName: string, id: string): Promise<boolean>;\n invalidate(modelName: string, id: string): Promise<void>;\n invalidateAll(modelName?: string): Promise<void>;\n}\n","import { RESPONSE_HEADERS } from './types.js';\n\nconst DEFAULT_TTL = 3_600_000;\n\nexport function parseCacheTTLFromHeaders(headers: Record<string, string>): number {\n const cacheControl = headers['cache-control'];\n if (cacheControl) {\n if (/no-store/i.test(cacheControl) || /no-cache/i.test(cacheControl)) {\n return 0;\n }\n const sMaxAge = /s-maxage=(\\d+)/i.exec(cacheControl);\n if (sMaxAge) {\n return parseInt(sMaxAge[1]!, 10) * 1000;\n }\n const maxAge = /max-age=(\\d+)/i.exec(cacheControl);\n if (maxAge) {\n return parseInt(maxAge[1]!, 10) * 1000;\n }\n }\n\n const expires = headers['expires'];\n if (expires) {\n const expiresMilliseconds = new Date(expires).getTime();\n if (!Number.isNaN(expiresMilliseconds)) {\n return Math.max(0, expiresMilliseconds - Date.now());\n }\n }\n\n return DEFAULT_TTL;\n}\n\nexport function extractResponseHeaders(\n payload: unknown,\n): Record<string, string> | null {\n if (payload !== null && typeof payload === 'object') {\n return (\n (payload as Record<symbol, unknown>)[RESPONSE_HEADERS] as\n | Record<string, string>\n | undefined\n ) ?? null;\n }\n return null;\n}\n\nexport function attachResponseHeaders(\n payload: unknown,\n headers: Record<string, string>,\n): void {\n if (payload !== null && typeof payload === 'object') {\n Object.defineProperty(payload, RESPONSE_HEADERS, {\n value: headers,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n }\n}\n"],"names":["RESPONSE_HEADERS","DEFAULT_TTL","parseCacheTTLFromHeaders","headers","cacheControl","sMaxAge","maxAge","expires","expiresMilliseconds","extractResponseHeaders","payload","attachResponseHeaders"],"mappings":"AAEO,MAAMA,IAAkC,OAAO,kBAAkB,GCAlEC,IAAc;AAEb,SAASC,EAAyBC,GAAyC;AAChF,QAAMC,IAAeD,EAAQ,eAAe;AAC5C,MAAIC,GAAc;AAChB,QAAI,YAAY,KAAKA,CAAY,KAAK,YAAY,KAAKA,CAAY;AACjE,aAAO;AAET,UAAMC,IAAU,kBAAkB,KAAKD,CAAY;AACnD,QAAIC;AACF,aAAO,SAASA,EAAQ,CAAC,GAAI,EAAE,IAAI;AAErC,UAAMC,IAAS,iBAAiB,KAAKF,CAAY;AACjD,QAAIE;AACF,aAAO,SAASA,EAAO,CAAC,GAAI,EAAE,IAAI;AAAA,EAEtC;AAEA,QAAMC,IAAUJ,EAAQ;AACxB,MAAII,GAAS;AACX,UAAMC,IAAsB,IAAI,KAAKD,CAAO,EAAE,QAAA;AAC9C,QAAI,CAAC,OAAO,MAAMC,CAAmB;AACnC,aAAO,KAAK,IAAI,GAAGA,IAAsB,KAAK,KAAK;AAAA,EAEvD;AAEA,SAAOP;AACT;AAEO,SAASQ,EACdC,GAC+B;AAC/B,SAAIA,MAAY,QAAQ,OAAOA,KAAY,WAEtCA,EAAoCV,CAAgB,KAGlD,OAEA;AACT;AAEO,SAASW,EACdD,GACAP,GACM;AACN,EAAIO,MAAY,QAAQ,OAAOA,KAAY,YACzC,OAAO,eAAeA,GAASV,GAAkB;AAAA,IAC/C,OAAOG;AAAA,IACP,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAAA,CACf;AAEL;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";require("reflect-metadata");const i=require("./types-uWOXMPWW.cjs");function r(e){let n=Reflect.getOwnMetadata(i.ATTRIBUTES_META_KEY,e);return n||(n=new Map,Reflect.defineMetadata(i.ATTRIBUTES_META_KEY,n,e)),n}function c(e){let n=Reflect.getOwnMetadata(i.RELATIONSHIPS_META_KEY,e);return n||(n=new Map,Reflect.defineMetadata(i.RELATIONSHIPS_META_KEY,n,e)),n}function o(e,n){let t=null,a={};return typeof e=="string"?(t=e,a=n??{}):e===null?(t=null,a=n??{}):typeof e=="object"&&e!==null&&(a=e),(s,l)=>{r(s).set(l,{name:l,type:t,options:a,isAttribute:!0})}}function u(e,n,t={}){const a={async:t.async??!1,inverse:t.inverse===void 0?null:t.inverse,polymorphic:t.polymorphic??!1,...t};return(s,l)=>{c(s).set(l,{name:l,kind:e,type:n,options:a,isRelationship:!0})}}function T(e,n={}){return u("belongsTo",e,n)}function M(e,n={}){return u("hasMany",e,n)}exports.attr=o;exports.belongsTo=T;exports.hasMany=M;
|
|
2
|
-
//# sourceMappingURL=decorators-HQ1KnRdh.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decorators-HQ1KnRdh.cjs","sources":["../src/schema/decorators.ts"],"sourcesContent":["/**\n * Property decorators for declaring model attributes and relationships.\n *\n * `@attr` marks a property as a data attribute that is serialized to/from the\n * server payload. `@belongsTo` and `@hasMany` declare the two supported\n * association directions.\n *\n * All decorators write their metadata onto the class prototype via\n * `reflect-metadata` so `SchemaService` can walk the prototype chain and\n * merge inherited definitions.\n */\n\nimport 'reflect-metadata';\nimport {\n ATTRIBUTES_META_KEY,\n RELATIONSHIPS_META_KEY,\n type AttributeDef,\n type AttributeOptions,\n type RelationshipDef,\n type RelationshipOptions,\n} from './types.js';\n\n/**\n * Returns the own-prototype attribute map for `target`, creating one if it\n * doesn't exist yet. We deliberately avoid inheriting the parent map so each\n * class level stores only its own declarations; `SchemaService.walkPrototypeChain`\n * handles merging.\n */\nfunction getOwnAttrMap(target: object): Map<string, AttributeDef> {\n let map = Reflect.getOwnMetadata(ATTRIBUTES_META_KEY, target) as\n | Map<string, AttributeDef>\n | undefined;\n if (!map) {\n map = new Map();\n Reflect.defineMetadata(ATTRIBUTES_META_KEY, map, target);\n }\n return map;\n}\n\n/**\n * Returns the own-prototype relationship map for `target`, creating one if\n * it doesn't exist yet.\n */\nfunction getOwnRelMap(target: object): Map<string, RelationshipDef> {\n let map = Reflect.getOwnMetadata(RELATIONSHIPS_META_KEY, target) as\n | Map<string, RelationshipDef>\n | undefined;\n if (!map) {\n map = new Map();\n Reflect.defineMetadata(RELATIONSHIPS_META_KEY, map, target);\n }\n return map;\n}\n\n/**\n * Marks a class property as a serializable attribute.\n *\n * @example\n * ```ts\n * @attr('string') name!: string;\n * @attr('number', { defaultValue: 0 }) age!: number;\n * @attr({ defaultValue: () => [] }) tags!: string[];\n * ```\n */\nexport function attr(\n type?: string | null,\n options?: AttributeOptions,\n): PropertyDecorator;\nexport function attr(options: AttributeOptions): PropertyDecorator;\nexport function attr(\n typeOrOptions?: string | null | AttributeOptions,\n options?: AttributeOptions,\n): PropertyDecorator {\n let resolvedType: string | null = null;\n let resolvedOptions: AttributeOptions = {};\n\n if (typeof typeOrOptions === 'string') {\n resolvedType = typeOrOptions;\n resolvedOptions = options ?? {};\n } else if (typeOrOptions === null) {\n resolvedType = null;\n resolvedOptions = options ?? {};\n } else if (typeof typeOrOptions === 'object' && typeOrOptions !== null) {\n resolvedOptions = typeOrOptions;\n }\n\n return (target, propertyKey) => {\n const map = getOwnAttrMap(target as object);\n map.set(propertyKey as string, {\n name: propertyKey as string,\n type: resolvedType,\n options: resolvedOptions,\n isAttribute: true,\n });\n };\n}\n\n/**\n * Builds and returns a `PropertyDecorator` that registers a relationship\n * definition on the class prototype. Shared by `@belongsTo` and `@hasMany`.\n *\n * Options are normalised with sensible defaults so consumers can rely on\n * `async`, `inverse`, and `polymorphic` always being present.\n */\nfunction makeRelationship(\n kind: 'belongsTo' | 'hasMany',\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n const normalized: RelationshipOptions = {\n async: options.async ?? false,\n inverse: options.inverse === undefined ? null : options.inverse,\n polymorphic: options.polymorphic ?? false,\n ...options,\n };\n return (target, propertyKey) => {\n const map = getOwnRelMap(target as object);\n map.set(propertyKey as string, {\n name: propertyKey as string,\n kind,\n type,\n options: normalized,\n isRelationship: true,\n });\n };\n}\n\n/**\n * Declares a `belongsTo` (many-to-one) association.\n *\n * @param type - `modelName` of the related model.\n * @param options - Optional relationship options (async, inverse, …).\n *\n * @example\n * ```ts\n * @belongsTo('user') author!: User;\n * ```\n */\nexport function belongsTo(\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n return makeRelationship('belongsTo', type, options);\n}\n\n/**\n * Declares a `hasMany` (one-to-many) association.\n *\n * @param type - `modelName` of the related model.\n * @param options - Optional relationship options (async, inverse, …).\n *\n * @example\n * ```ts\n * @hasMany('comment') comments!: Comment[];\n * ```\n */\nexport function hasMany(\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n return makeRelationship('hasMany', type, options);\n}\n"],"names":["getOwnAttrMap","target","map","ATTRIBUTES_META_KEY","getOwnRelMap","RELATIONSHIPS_META_KEY","attr","typeOrOptions","options","resolvedType","resolvedOptions","propertyKey","makeRelationship","kind","type","normalized","belongsTo","hasMany"],"mappings":"iFA4BA,SAASA,EAAcC,EAA2C,CAChE,IAAIC,EAAM,QAAQ,eAAeC,EAAAA,oBAAqBF,CAAM,EAG5D,OAAKC,IACHA,MAAU,IACV,QAAQ,eAAeC,sBAAqBD,EAAKD,CAAM,GAElDC,CACT,CAMA,SAASE,EAAaH,EAA8C,CAClE,IAAIC,EAAM,QAAQ,eAAeG,EAAAA,uBAAwBJ,CAAM,EAG/D,OAAKC,IACHA,MAAU,IACV,QAAQ,eAAeG,yBAAwBH,EAAKD,CAAM,GAErDC,CACT,CAiBO,SAASI,EACdC,EACAC,EACmB,CACnB,IAAIC,EAA8B,KAC9BC,EAAoC,CAAA,EAExC,OAAI,OAAOH,GAAkB,UAC3BE,EAAeF,EACfG,EAAkBF,GAAW,CAAA,GACpBD,IAAkB,MAC3BE,EAAe,KACfC,EAAkBF,GAAW,CAAA,GACpB,OAAOD,GAAkB,UAAYA,IAAkB,OAChEG,EAAkBH,GAGb,CAACN,EAAQU,IAAgB,CAClBX,EAAcC,CAAgB,EACtC,IAAIU,EAAuB,CAC7B,KAAMA,EACN,KAAMF,EACN,QAASC,EACT,YAAa,EAAA,CACd,CACH,CACF,CASA,SAASE,EACPC,EACAC,EACAN,EAA+B,CAAA,EACZ,CACnB,MAAMO,EAAkC,CACtC,MAAOP,EAAQ,OAAS,GACxB,QAASA,EAAQ,UAAY,OAAY,KAAOA,EAAQ,QACxD,YAAaA,EAAQ,aAAe,GACpC,GAAGA,CAAA,EAEL,MAAO,CAACP,EAAQU,IAAgB,CAClBP,EAAaH,CAAgB,EACrC,IAAIU,EAAuB,CAC7B,KAAMA,EACN,KAAAE,EACA,KAAAC,EACA,QAASC,EACT,eAAgB,EAAA,CACjB,CACH,CACF,CAaO,SAASC,EACdF,EACAN,EAA+B,GACZ,CACnB,OAAOI,EAAiB,YAAaE,EAAMN,CAAO,CACpD,CAaO,SAASS,EACdH,EACAN,EAA+B,GACZ,CACnB,OAAOI,EAAiB,UAAWE,EAAMN,CAAO,CAClD"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import "reflect-metadata";
|
|
2
|
-
import { A as s, R as f } from "./types-C9NB2gRj.js";
|
|
3
|
-
function c(e) {
|
|
4
|
-
let n = Reflect.getOwnMetadata(s, e);
|
|
5
|
-
return n || (n = /* @__PURE__ */ new Map(), Reflect.defineMetadata(s, n, e)), n;
|
|
6
|
-
}
|
|
7
|
-
function o(e) {
|
|
8
|
-
let n = Reflect.getOwnMetadata(f, e);
|
|
9
|
-
return n || (n = /* @__PURE__ */ new Map(), Reflect.defineMetadata(f, n, e)), n;
|
|
10
|
-
}
|
|
11
|
-
function d(e, n) {
|
|
12
|
-
let a = null, t = {};
|
|
13
|
-
return typeof e == "string" ? (a = e, t = n ?? {}) : e === null ? (a = null, t = n ?? {}) : typeof e == "object" && e !== null && (t = e), (i, l) => {
|
|
14
|
-
c(i).set(l, {
|
|
15
|
-
name: l,
|
|
16
|
-
type: a,
|
|
17
|
-
options: t,
|
|
18
|
-
isAttribute: !0
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function u(e, n, a = {}) {
|
|
23
|
-
const t = {
|
|
24
|
-
async: a.async ?? !1,
|
|
25
|
-
inverse: a.inverse === void 0 ? null : a.inverse,
|
|
26
|
-
polymorphic: a.polymorphic ?? !1,
|
|
27
|
-
...a
|
|
28
|
-
};
|
|
29
|
-
return (i, l) => {
|
|
30
|
-
o(i).set(l, {
|
|
31
|
-
name: l,
|
|
32
|
-
kind: e,
|
|
33
|
-
type: n,
|
|
34
|
-
options: t,
|
|
35
|
-
isRelationship: !0
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function R(e, n = {}) {
|
|
40
|
-
return u("belongsTo", e, n);
|
|
41
|
-
}
|
|
42
|
-
function T(e, n = {}) {
|
|
43
|
-
return u("hasMany", e, n);
|
|
44
|
-
}
|
|
45
|
-
export {
|
|
46
|
-
d as a,
|
|
47
|
-
R as b,
|
|
48
|
-
T as h
|
|
49
|
-
};
|
|
50
|
-
//# sourceMappingURL=decorators-Zr35qr6A.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decorators-Zr35qr6A.js","sources":["../src/schema/decorators.ts"],"sourcesContent":["/**\n * Property decorators for declaring model attributes and relationships.\n *\n * `@attr` marks a property as a data attribute that is serialized to/from the\n * server payload. `@belongsTo` and `@hasMany` declare the two supported\n * association directions.\n *\n * All decorators write their metadata onto the class prototype via\n * `reflect-metadata` so `SchemaService` can walk the prototype chain and\n * merge inherited definitions.\n */\n\nimport 'reflect-metadata';\nimport {\n ATTRIBUTES_META_KEY,\n RELATIONSHIPS_META_KEY,\n type AttributeDef,\n type AttributeOptions,\n type RelationshipDef,\n type RelationshipOptions,\n} from './types.js';\n\n/**\n * Returns the own-prototype attribute map for `target`, creating one if it\n * doesn't exist yet. We deliberately avoid inheriting the parent map so each\n * class level stores only its own declarations; `SchemaService.walkPrototypeChain`\n * handles merging.\n */\nfunction getOwnAttrMap(target: object): Map<string, AttributeDef> {\n let map = Reflect.getOwnMetadata(ATTRIBUTES_META_KEY, target) as\n | Map<string, AttributeDef>\n | undefined;\n if (!map) {\n map = new Map();\n Reflect.defineMetadata(ATTRIBUTES_META_KEY, map, target);\n }\n return map;\n}\n\n/**\n * Returns the own-prototype relationship map for `target`, creating one if\n * it doesn't exist yet.\n */\nfunction getOwnRelMap(target: object): Map<string, RelationshipDef> {\n let map = Reflect.getOwnMetadata(RELATIONSHIPS_META_KEY, target) as\n | Map<string, RelationshipDef>\n | undefined;\n if (!map) {\n map = new Map();\n Reflect.defineMetadata(RELATIONSHIPS_META_KEY, map, target);\n }\n return map;\n}\n\n/**\n * Marks a class property as a serializable attribute.\n *\n * @example\n * ```ts\n * @attr('string') name!: string;\n * @attr('number', { defaultValue: 0 }) age!: number;\n * @attr({ defaultValue: () => [] }) tags!: string[];\n * ```\n */\nexport function attr(\n type?: string | null,\n options?: AttributeOptions,\n): PropertyDecorator;\nexport function attr(options: AttributeOptions): PropertyDecorator;\nexport function attr(\n typeOrOptions?: string | null | AttributeOptions,\n options?: AttributeOptions,\n): PropertyDecorator {\n let resolvedType: string | null = null;\n let resolvedOptions: AttributeOptions = {};\n\n if (typeof typeOrOptions === 'string') {\n resolvedType = typeOrOptions;\n resolvedOptions = options ?? {};\n } else if (typeOrOptions === null) {\n resolvedType = null;\n resolvedOptions = options ?? {};\n } else if (typeof typeOrOptions === 'object' && typeOrOptions !== null) {\n resolvedOptions = typeOrOptions;\n }\n\n return (target, propertyKey) => {\n const map = getOwnAttrMap(target as object);\n map.set(propertyKey as string, {\n name: propertyKey as string,\n type: resolvedType,\n options: resolvedOptions,\n isAttribute: true,\n });\n };\n}\n\n/**\n * Builds and returns a `PropertyDecorator` that registers a relationship\n * definition on the class prototype. Shared by `@belongsTo` and `@hasMany`.\n *\n * Options are normalised with sensible defaults so consumers can rely on\n * `async`, `inverse`, and `polymorphic` always being present.\n */\nfunction makeRelationship(\n kind: 'belongsTo' | 'hasMany',\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n const normalized: RelationshipOptions = {\n async: options.async ?? false,\n inverse: options.inverse === undefined ? null : options.inverse,\n polymorphic: options.polymorphic ?? false,\n ...options,\n };\n return (target, propertyKey) => {\n const map = getOwnRelMap(target as object);\n map.set(propertyKey as string, {\n name: propertyKey as string,\n kind,\n type,\n options: normalized,\n isRelationship: true,\n });\n };\n}\n\n/**\n * Declares a `belongsTo` (many-to-one) association.\n *\n * @param type - `modelName` of the related model.\n * @param options - Optional relationship options (async, inverse, …).\n *\n * @example\n * ```ts\n * @belongsTo('user') author!: User;\n * ```\n */\nexport function belongsTo(\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n return makeRelationship('belongsTo', type, options);\n}\n\n/**\n * Declares a `hasMany` (one-to-many) association.\n *\n * @param type - `modelName` of the related model.\n * @param options - Optional relationship options (async, inverse, …).\n *\n * @example\n * ```ts\n * @hasMany('comment') comments!: Comment[];\n * ```\n */\nexport function hasMany(\n type: string,\n options: RelationshipOptions = {},\n): PropertyDecorator {\n return makeRelationship('hasMany', type, options);\n}\n"],"names":["getOwnAttrMap","target","map","ATTRIBUTES_META_KEY","getOwnRelMap","RELATIONSHIPS_META_KEY","attr","typeOrOptions","options","resolvedType","resolvedOptions","propertyKey","makeRelationship","kind","type","normalized","belongsTo","hasMany"],"mappings":";;AA4BA,SAASA,EAAcC,GAA2C;AAChE,MAAIC,IAAM,QAAQ,eAAeC,GAAqBF,CAAM;AAG5D,SAAKC,MACHA,wBAAU,IAAA,GACV,QAAQ,eAAeC,GAAqBD,GAAKD,CAAM,IAElDC;AACT;AAMA,SAASE,EAAaH,GAA8C;AAClE,MAAIC,IAAM,QAAQ,eAAeG,GAAwBJ,CAAM;AAG/D,SAAKC,MACHA,wBAAU,IAAA,GACV,QAAQ,eAAeG,GAAwBH,GAAKD,CAAM,IAErDC;AACT;AAiBO,SAASI,EACdC,GACAC,GACmB;AACnB,MAAIC,IAA8B,MAC9BC,IAAoC,CAAA;AAExC,SAAI,OAAOH,KAAkB,YAC3BE,IAAeF,GACfG,IAAkBF,KAAW,CAAA,KACpBD,MAAkB,QAC3BE,IAAe,MACfC,IAAkBF,KAAW,CAAA,KACpB,OAAOD,KAAkB,YAAYA,MAAkB,SAChEG,IAAkBH,IAGb,CAACN,GAAQU,MAAgB;AAE9B,IADYX,EAAcC,CAAgB,EACtC,IAAIU,GAAuB;AAAA,MAC7B,MAAMA;AAAA,MACN,MAAMF;AAAA,MACN,SAASC;AAAA,MACT,aAAa;AAAA,IAAA,CACd;AAAA,EACH;AACF;AASA,SAASE,EACPC,GACAC,GACAN,IAA+B,CAAA,GACZ;AACnB,QAAMO,IAAkC;AAAA,IACtC,OAAOP,EAAQ,SAAS;AAAA,IACxB,SAASA,EAAQ,YAAY,SAAY,OAAOA,EAAQ;AAAA,IACxD,aAAaA,EAAQ,eAAe;AAAA,IACpC,GAAGA;AAAA,EAAA;AAEL,SAAO,CAACP,GAAQU,MAAgB;AAE9B,IADYP,EAAaH,CAAgB,EACrC,IAAIU,GAAuB;AAAA,MAC7B,MAAMA;AAAA,MACN,MAAAE;AAAA,MACA,MAAAC;AAAA,MACA,SAASC;AAAA,MACT,gBAAgB;AAAA,IAAA,CACjB;AAAA,EACH;AACF;AAaO,SAASC,EACdF,GACAN,IAA+B,IACZ;AACnB,SAAOI,EAAiB,aAAaE,GAAMN,CAAO;AACpD;AAaO,SAASS,EACdH,GACAN,IAA+B,IACZ;AACnB,SAAOI,EAAiB,WAAWE,GAAMN,CAAO;AAClD;"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";require("reflect-metadata");const i=require("mobx"),h=require("./types-uWOXMPWW.cjs"),_=require("tsyringe");var y=Object.getOwnPropertyDescriptor,b=(a,t,e,r)=>{for(var s=r>1?void 0:r?y(t,e):t,o=a.length-1,n;o>=0;o--)(n=a[o])&&(s=n(s)||s);return s};exports.Errors=class{constructor(){this._errors=new Map,i.makeObservable(this,{_errors:i.observable.shallow,isEmpty:i.computed,length:i.computed,add:i.action,remove:i.action,clear:i.action})}get isEmpty(){return this._errors.size===0}get length(){let t=0;for(const e of this._errors.values())t+=e.length;return t}get(t){return this._errors.get(t)??[]}has(t){const e=this._errors.get(t);return!!e&&e.length>0}add(t,e){const r=Array.isArray(e)?e:[e],o=[...this._errors.get(t)??[],...r.map(n=>({attribute:t,message:n}))];this._errors.set(t,o)}remove(t){this._errors.delete(t)}clear(){this._errors.clear()}*[Symbol.iterator](){for(const t of this._errors.entries())yield t}};exports.Errors=b([_.injectable()],exports.Errors);const S={"root.empty":{loadingData:"root.loading",pushedData:"root.loaded.saved"},"root.loading":{pushedData:"root.loaded.saved",becameError:"root.error"},"root.loaded.saved":{didSetProperty:"root.loaded.updated.uncommitted",deleteRecord:"root.deleted.uncommitted",loadingData:"root.loading",pushedData:"root.loaded.saved",unloadRecord:"root.empty"},"root.loaded.created.uncommitted":{willCommit:"root.loaded.created.inFlight",rolledBack:"root.empty",deleteRecord:"root.deleted.uncommitted",didSetProperty:"root.loaded.created.uncommitted",unloadRecord:"root.empty"},"root.loaded.created.inFlight":{didCommit:"root.loaded.saved",becameInvalid:"root.loaded.created.uncommitted",becameError:"root.error"},"root.loaded.updated.uncommitted":{willCommit:"root.loaded.updated.inFlight",rolledBack:"root.loaded.saved",didSetProperty:"root.loaded.updated.uncommitted",deleteRecord:"root.deleted.uncommitted",unloadRecord:"root.empty"},"root.loaded.updated.inFlight":{didCommit:"root.loaded.saved",becameInvalid:"root.loaded.updated.uncommitted",becameError:"root.error"},"root.deleted.uncommitted":{willCommit:"root.deleted.inFlight",rolledBack:"root.loaded.saved",unloadRecord:"root.empty"},"root.deleted.inFlight":{didCommit:"root.deleted.saved",becameError:"root.error"},"root.deleted.saved":{unloadRecord:"root.empty"},"root.error":{rolledBack:"root.loaded.saved",unloadRecord:"root.empty"}};class p{constructor(t="root.empty"){this.current=t,i.makeObservable(this,{current:i.observable,transition:i.action})}transition(t){const e=S[this.current][t];if(!e)throw new Error(`Invalid transition: event "${t}" not allowed from state "${this.current}"`);return this.current=e,e}}function u(a,t){const e=[];let r=a;for(;r&&r!==Object.prototype;)e.push(r),r=Object.getPrototypeOf(r);const s=new Map;for(const o of e.reverse()){const n=Reflect.getOwnMetadata(t,o);if(n)for(const[l,c]of n)s.set(l,c)}return s}class g{constructor(t){this.record=t,this.id=t.id,this.modelName=t.modelName;const e=t;this._attributes={...e._data},this._relationships=new Map(e._relationships),this._changedAttributes=t.changedAttributes();const r=Object.getPrototypeOf(t);this._attributeDefinitions=u(r,h.ATTRIBUTES_META_KEY),this._relationshipDefinitions=u(r,h.RELATIONSHIPS_META_KEY)}attr(t){return this._attributes[t]}belongsTo(t,e){const r=this._relationships.get(t);if(!r||r.data===null)return null;const s=r.data;return e!=null&&e.id?s.id:{id:s.id,type:s.type}}hasMany(t,e){const r=this._relationships.get(t);if(!r||!Array.isArray(r.data))return[];const s=r.data;return e!=null&&e.ids?s.map(o=>o.id):s.map(o=>({id:o.id,type:o.type}))}changedAttributes(){return{...this._changedAttributes}}eachAttribute(t){for(const[e,r]of this._attributeDefinitions)t(e,r)}eachRelationship(t){for(const[e,r]of this._relationshipDefinitions)t(e,r)}}const m=Symbol("mobx-data:accessors-installed");function f(a,t){const e=[];let r=a;for(;r&&r!==Object.prototype;)e.push(r),r=Object.getPrototypeOf(r);const s=new Map;for(const o of e.reverse()){const n=Reflect.getOwnMetadata(t,o);if(n)for(const[l,c]of n)s.set(l,c)}return s}function v(a){const t=a.prototype;if(a[m])return;a[m]=!0;const e=f(t,h.ATTRIBUTES_META_KEY);for(const[s]of e)Object.defineProperty(t,s,{get(){return this._data[s]},set(o){this._setAttribute(s,o)},configurable:!0,enumerable:!0});const r=f(t,h.RELATIONSHIPS_META_KEY);for(const[s,o]of r)Object.defineProperty(t,s,{get(){return this._resolveRelationship(s,o)},set(n){this._setRelationship(s,o,n)},configurable:!0,enumerable:!0})}class R{constructor(t={}){this._data={},this._originalData={},this._relationships=new Map,this._id=null,this.errors=new exports.Errors;const e=t;v(this.constructor),this._id=e.id??null,this.store=e.store,this._stateMachine=new p(e.__initialState??"root.loaded.created.uncommitted");const r=e.data?{...e.data}:{};if(this._data=r,e.__initialState==="root.loaded.saved"?this._originalData={...r}:this._originalData={},e.relationships)for(const[s,o]of Object.entries(e.relationships))this._relationships.set(s,o);i.makeObservable(this,{_data:i.observable.shallow,_originalData:i.observable.ref,_relationships:i.observable.shallow,_id:i.observable,id:i.computed,currentState:i.computed,isLoading:i.computed,isLoaded:i.computed,isSaving:i.computed,isDirty:i.computed,hasDirtyAttributes:i.computed,isNew:i.computed,isDeleted:i.computed,isValid:i.computed,isError:i.computed,isEmpty:i.computed,_setAttribute:i.action,_transitionIfClean:i.action,_applyServerData:i.action,_setState:i.action,rollbackAttributes:i.action,deleteRecord:i.action})}static push(t){const e=this,r=new e({...t,__initialState:"root.loaded.saved"});return r.didLoad(),r}get id(){return this._id}set id(t){i.runInAction(()=>{this._id=t})}get modelName(){return this.constructor.modelName}get currentState(){return this._stateMachine.current}get isLoading(){return this.currentState==="root.loading"}get isLoaded(){return this.currentState.startsWith("root.loaded")}get isSaving(){return this.currentState.endsWith(".inFlight")}get isNew(){return this.currentState.startsWith("root.loaded.created")}get isDeleted(){return this.currentState.startsWith("root.deleted")}get isError(){return this.currentState==="root.error"}get isEmpty(){return this.currentState==="root.empty"}get hasDirtyAttributes(){const t=this._data,e=this._originalData;for(const r of Object.keys(t))if(!Object.is(t[r],e[r]))return!0;for(const r of Object.keys(e))if(!(r in t))return!0;return!1}get isDirty(){return this.isNew||this.isDeleted&&this.currentState!=="root.deleted.saved"?!0:this.hasDirtyAttributes}get isValid(){return this.errors.isEmpty}changedAttributes(){const t={},e=new Set([...Object.keys(this._data),...Object.keys(this._originalData)]);for(const r of e){const s=this._data[r],o=this._originalData[r];Object.is(s,o)||(t[r]=[o,s])}return t}rollbackAttributes(){var t;if(this._data={...this._originalData},this.errors.clear(),this.isNew){this._setState("root.empty"),(t=this.store)!=null&&t.unloadRecord&&this.store.unloadRecord(this);return}this.currentState==="root.loaded.updated.uncommitted"?this._stateMachine.transition("rolledBack"):this.currentState==="root.deleted.uncommitted"&&this._stateMachine.transition("rolledBack")}async save(t={}){var r;if(!this.isDirty)return this;if(!((r=this.store)!=null&&r.saveRecord))throw new Error("Cannot save: no store attached");const e=this.isNew;this.willSave(),this._stateMachine.transition("willCommit");try{return await this.store.saveRecord(this,t),(this.currentState==="root.loaded.created.inFlight"||this.currentState==="root.loaded.updated.inFlight")&&i.runInAction(()=>{this._originalData={...this._data},this._stateMachine.transition("didCommit")}),e?this.didCreate():this.didUpdate(),this.didSave(),this}catch(s){throw this.errors.isEmpty?(this._stateMachine.transition("becameError"),this.becameError()):(this._stateMachine.transition("becameInvalid"),this.becameInvalid()),s}}async reload(){var t;if(!((t=this.store)!=null&&t.reloadRecord))throw new Error("Cannot reload: no store attached");return await this.store.reloadRecord(this)}deleteRecord(){this.isNew?this._setState("root.deleted.uncommitted"):this._stateMachine.transition("deleteRecord")}async destroyRecord(){var e;if(this.deleteRecord(),!((e=this.store)!=null&&e.deleteRecord))throw new Error("Cannot destroy: no store attached");this._stateMachine.transition("willCommit");const t=await this.store.deleteRecord(this);return this.currentState==="root.deleted.inFlight"&&this._stateMachine.transition("didCommit"),this.didDelete(),t}unloadRecord(){var t;(t=this.store)!=null&&t.unloadRecord&&this.store.unloadRecord(this)}createSnapshot(){return new g(this)}serialize(t={}){return{...this._data}}toJSON(){return{id:this._id,...this._data}}didLoad(){}didCreate(){}didUpdate(){}didDelete(){}willSave(){}didSave(){}becameInvalid(){}becameError(){}_setAttribute(t,e){Object.is(this._data[t],e)||(this._data[t]=e,this._transitionIfClean())}_transitionIfClean(){const t=this.hasDirtyAttributes;t&&this.currentState==="root.loaded.saved"?this._stateMachine.transition("didSetProperty"):!t&&this.currentState==="root.loaded.updated.uncommitted"&&this._stateMachine.transition("rolledBack")}_setState(t){this._stateMachine.current=t}_transition(t){this._stateMachine.transition(t)}_applyServerData(t,e,r){if(t!==null&&(this._id=t),this._data={...this._data,...e},this._originalData={...this._data},this.errors.clear(),r)for(const[s,o]of Object.entries(r))this._relationships.set(s,o);this.currentState==="root.loaded.created.inFlight"?(this._stateMachine.transition("didCommit"),this.didCreate()):this.currentState==="root.loaded.updated.inFlight"?(this._stateMachine.transition("didCommit"),this.didUpdate()):this.currentState==="root.deleted.inFlight"?this._stateMachine.transition("didCommit"):this.currentState==="root.loading"&&this._stateMachine.transition("pushedData"),!this.isNew&&!this.isDeleted&&(this.currentState==="root.loaded.updated.uncommitted"||this.currentState==="root.loaded.created.uncommitted")&&this._setState("root.loaded.saved")}_getRelationshipRef(t){return this._relationships.get(t)??null}_setRelationshipRef(t,e){this._relationships.set(t,e)}_resolveRelationship(t,e){var r;return(r=this.store)!=null&&r.resolveRelationship?this.store.resolveRelationship(this,t,e):null}_setRelationship(t,e,r){var s;(s=this.store)!=null&&s.setRelationshipValue&&this.store.setRelationshipValue(this,t,e,r)}}class d{static refData(t){return!t||!t.data?[]:Array.isArray(t.data)?t.data:[]}constructor(t){this.host=t,i.makeObservable(this,{resolved:i.computed,length:i.computed,push:i.action,removeObject:i.action})}get resolved(){const t=this.host.store._getRelationshipRefFor(this.host.parent,this.host.name),e=[],r=new Set;for(const o of d.refData(t)){const n=this.host.store.peekRecord(o.type,o.id);n&&(e.push(n),r.add(n))}const s=this.host.store._getPendingMembers(this.host.parent,this.host.name);for(const o of s)r.has(o)||e.push(o);return e}get length(){return this.resolved.length}at(t){return this.resolved[t]}push(...t){for(const e of t)this.host.store._hasManyAppend(this.host.parent,this.host.name,this.host.meta,e);return this.length}removeObject(t){this.host.store._hasManyRemove(this.host.parent,this.host.name,this.host.meta,t)}includes(t){return this.resolved.includes(t)}toArray(){return[...this.resolved]}map(t){return this.resolved.map(t)}filter(t){return this.resolved.filter(t)}forEach(t){this.resolved.forEach(t)}[Symbol.iterator](){return this.resolved[Symbol.iterator]()}}class A{constructor(t){this.loadedState="pending",this.currentValue=null,this.error=null,this.inflight=null,this.host=t,i.makeObservable(this,{loadedState:i.observable,currentValue:i.observable.ref,error:i.observable.ref,isPending:i.computed,isFulfilled:i.computed,isRejected:i.computed,isLoaded:i.computed,isLoading:i.computed,value:i.computed,reason:i.computed,syncFromCache:i.action}),this.syncFromCache()}syncFromCache(){const t=this.host.store._getRelationshipRefFor(this.host.parent,this.host.name);if(!t||!t.data||Array.isArray(t.data)){this.currentValue=null,this.loadedState="fulfilled";return}const e=this.host.store.peekRecord(t.data.type,t.data.id);e&&(this.currentValue=e,this.loadedState="fulfilled")}get isPending(){return this.loadedState==="pending"}get isFulfilled(){return this.loadedState==="fulfilled"}get isRejected(){return this.loadedState==="rejected"}get isLoading(){return this.inflight!==null&&this.isPending}get isLoaded(){return this.loadedState==="fulfilled"}get value(){return this.currentValue}get reason(){return this.error}load(){if(this.syncFromCache(),this.loadedState==="fulfilled"&&this.currentValue)return Promise.resolve(this.currentValue);if(this.inflight)return this.inflight;const t=this.host.store._getRelationshipRefFor(this.host.parent,this.host.name);if(!t||!t.data||Array.isArray(t.data))return Promise.resolve(null);const{type:e,id:r}=t.data;return this.inflight=this.host.store.findRecord(e,r).then(s=>(i.runInAction(()=>{this.currentValue=s,this.loadedState="fulfilled",this.inflight=null}),s),s=>{throw i.runInAction(()=>{this.error=s,this.loadedState="rejected",this.inflight=null}),s}),this.inflight}reload(){return this.inflight=null,this.loadedState="pending",this.load()}then(t,e){return this.load().then(t,e)}}class w{constructor(t){this.loadedState="pending",this.error=null,this.inflight=null,this.host=t,this.manyArray=new d(t),i.makeObservable(this,{loadedState:i.observable,error:i.observable.ref,isPending:i.computed,isFulfilled:i.computed,isRejected:i.computed,isLoaded:i.computed,isLoading:i.computed,length:i.computed,syncFromCache:i.action}),this.syncFromCache()}syncFromCache(){const t=this.host.store._getRelationshipRefFor(this.host.parent,this.host.name);d.refData(t).every(s=>this.host.store.peekRecord(s.type,s.id)!==null)&&(this.loadedState="fulfilled")}get isPending(){return this.loadedState==="pending"}get isFulfilled(){return this.loadedState==="fulfilled"}get isRejected(){return this.loadedState==="rejected"}get isLoading(){return this.inflight!==null&&this.isPending}get isLoaded(){return this.loadedState==="fulfilled"}get value(){return this.manyArray}get length(){return this.manyArray.length}load(){if(this.syncFromCache(),this.loadedState==="fulfilled")return Promise.resolve(this.manyArray);if(this.inflight)return this.inflight;const t=this.host.store._getRelationshipRefFor(this.host.parent,this.host.name),s=d.refData(t).filter(o=>this.host.store.peekRecord(o.type,o.id)===null).map(o=>this.host.store.findRecord(o.type,o.id));return this.inflight=Promise.all(s).then(()=>(i.runInAction(()=>{this.loadedState="fulfilled",this.inflight=null}),this.manyArray),o=>{throw i.runInAction(()=>{this.error=o,this.loadedState="rejected",this.inflight=null}),o}),this.inflight}reload(){return this.inflight=null,this.loadedState="pending",this.load()}then(t,e){return this.load().then(t,e)}}exports.AsyncBelongsTo=A;exports.AsyncHasMany=w;exports.ManyArray=d;exports.Model=R;exports.Snapshot=g;exports.StateMachine=p;
|
|
2
|
-
//# sourceMappingURL=relationships-B55LBaCW.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"relationships-B55LBaCW.cjs","sources":["../src/model/Errors.ts","../src/model/StateMachine.ts","../src/model/Snapshot.ts","../src/model/Model.ts","../src/model/relationships.ts"],"sourcesContent":["/**\n * Observable collection of validation error messages keyed by attribute name.\n *\n * `Errors` is attached to every `Model` instance as `record.errors`. It\n * mirrors Ember Data's `DS.Errors` API: each attribute can hold multiple\n * `ErrorMessage` objects, and the map is MobX-observable so templates / computed\n * properties that read `isEmpty` or `length` react automatically when errors\n * are added or cleared.\n *\n * Typical lifecycle:\n * 1. Server returns a 422; the serializer calls `store.errors.add(…)`.\n * 2. The UI reads `record.errors.get('email')` to display messages.\n * 3. The user corrects the field; `record.errors.remove('email')` clears it.\n * 4. A successful save calls `record.errors.clear()` to wipe all messages.\n */\n\nimport { injectable } from 'tsyringe';\nimport {\n makeObservable, observable, computed, action,\n} from 'mobx';\n\n/** A single validation error for one attribute. */\nexport interface ErrorMessage {\n /** Attribute name the error belongs to. */\n attribute: string;\n /** Human-readable error message. */\n message: string;\n}\n\n@injectable()\nexport class Errors implements Iterable<[string, ErrorMessage[]]> {\n private _errors: Map<string, ErrorMessage[]> = new Map();\n\n constructor() {\n makeObservable<this, '_errors'>(this, {\n _errors: observable.shallow,\n isEmpty: computed,\n length: computed,\n add: action,\n remove: action,\n clear: action,\n });\n }\n\n /** `true` when there are no validation errors. */\n get isEmpty(): boolean {\n return this._errors.size === 0;\n }\n\n /** Total number of error messages across all attributes. */\n get length(): number {\n let total = 0;\n for (const messages of this._errors.values()) {\n total += messages.length;\n }\n return total;\n }\n\n /** Returns all error messages for `attribute`, or an empty array. */\n get(attribute: string): ErrorMessage[] {\n return this._errors.get(attribute) ?? [];\n }\n\n /** Returns `true` when `attribute` has at least one error message. */\n has(attribute: string): boolean {\n const messages = this._errors.get(attribute);\n return !!messages && messages.length > 0;\n }\n\n /**\n * Appends one or more error messages for `attribute`.\n * Existing messages are preserved — this is an additive operation.\n */\n add(attribute: string, message: string | string[]): void {\n const incoming = Array.isArray(message) ? message : [message];\n const existing = this._errors.get(attribute) ?? [];\n const next: ErrorMessage[] = [\n ...existing,\n ...incoming.map((msg) => ({ attribute, message: msg })),\n ];\n this._errors.set(attribute, next);\n }\n\n /** Removes all error messages for `attribute`. */\n remove(attribute: string): void {\n this._errors.delete(attribute);\n }\n\n /** Removes all error messages for every attribute. */\n clear(): void {\n this._errors.clear();\n }\n\n /** Iterates `[attributeName, ErrorMessage[]]` pairs. */\n * [Symbol.iterator](): Iterator<[string, ErrorMessage[]]> {\n for (const entry of this._errors.entries()) {\n yield entry;\n }\n }\n}\n","/**\n * Finite-state machine that tracks the lifecycle of a single model record.\n *\n * States are organised in a dot-separated hierarchy that mirrors Ember Data's\n * record state machine. The transition table (`TABLE`) is the single source\n * of truth; illegal transitions throw immediately rather than silently\n * degrading into an unexpected state.\n *\n * State hierarchy overview:\n * ```\n * root.empty\n * root.loading\n * root.loaded\n * .saved\n * .created.uncommitted ← new record, not yet sent to server\n * .created.inFlight ← POST in progress\n * .updated.uncommitted ← dirty record, not yet sent to server\n * .updated.inFlight ← PUT/PATCH in progress\n * root.deleted\n * .uncommitted ← deleteRecord() called locally\n * .inFlight ← DELETE in progress\n * .saved ← server confirmed deletion\n * root.error ← adapter threw an unrecoverable error\n * ```\n *\n * `current` is MobX-observable so computed properties that depend on\n * `isNew`, `isDirty`, etc. react automatically.\n */\n\nimport { makeObservable, observable, action } from 'mobx';\n\n/** All valid states the record can be in. */\nexport type RecordState =\n | 'root.empty'\n | 'root.loading'\n | 'root.loaded.saved'\n | 'root.loaded.created.uncommitted'\n | 'root.loaded.created.inFlight'\n | 'root.loaded.updated.uncommitted'\n | 'root.loaded.updated.inFlight'\n | 'root.deleted.uncommitted'\n | 'root.deleted.inFlight'\n | 'root.deleted.saved'\n | 'root.error';\n\n/** Events that trigger state transitions. */\nexport type RecordEvent =\n | 'loadingData'\n | 'pushedData'\n | 'becameError'\n | 'didSetProperty'\n | 'willCommit'\n | 'didCommit'\n | 'becameInvalid'\n | 'deleteRecord'\n | 'rolledBack'\n | 'unloadRecord';\n\n/** Per-state map of allowed events → destination states. */\ntype Transitions = Partial<Record<RecordEvent, RecordState>>;\n\n/** Complete transition table. A missing entry means the transition is invalid. */\nconst TABLE: Record<RecordState, Transitions> = {\n 'root.empty': {\n loadingData: 'root.loading',\n pushedData: 'root.loaded.saved',\n },\n 'root.loading': {\n pushedData: 'root.loaded.saved',\n becameError: 'root.error',\n },\n 'root.loaded.saved': {\n didSetProperty: 'root.loaded.updated.uncommitted',\n deleteRecord: 'root.deleted.uncommitted',\n loadingData: 'root.loading',\n pushedData: 'root.loaded.saved',\n unloadRecord: 'root.empty',\n },\n 'root.loaded.created.uncommitted': {\n willCommit: 'root.loaded.created.inFlight',\n rolledBack: 'root.empty',\n deleteRecord: 'root.deleted.uncommitted',\n didSetProperty: 'root.loaded.created.uncommitted',\n unloadRecord: 'root.empty',\n },\n 'root.loaded.created.inFlight': {\n didCommit: 'root.loaded.saved',\n becameInvalid: 'root.loaded.created.uncommitted',\n becameError: 'root.error',\n },\n 'root.loaded.updated.uncommitted': {\n willCommit: 'root.loaded.updated.inFlight',\n rolledBack: 'root.loaded.saved',\n didSetProperty: 'root.loaded.updated.uncommitted',\n deleteRecord: 'root.deleted.uncommitted',\n unloadRecord: 'root.empty',\n },\n 'root.loaded.updated.inFlight': {\n didCommit: 'root.loaded.saved',\n becameInvalid: 'root.loaded.updated.uncommitted',\n becameError: 'root.error',\n },\n 'root.deleted.uncommitted': {\n willCommit: 'root.deleted.inFlight',\n rolledBack: 'root.loaded.saved',\n unloadRecord: 'root.empty',\n },\n 'root.deleted.inFlight': {\n didCommit: 'root.deleted.saved',\n becameError: 'root.error',\n },\n 'root.deleted.saved': {\n unloadRecord: 'root.empty',\n },\n 'root.error': {\n rolledBack: 'root.loaded.saved',\n unloadRecord: 'root.empty',\n },\n};\n\nexport class StateMachine {\n /** The current state of the record. Observable so computed props react. */\n current: RecordState;\n\n constructor(initial: RecordState = 'root.empty') {\n this.current = initial;\n makeObservable(this, {\n current: observable,\n transition: action,\n });\n }\n\n /**\n * Applies `event` to the current state, updates `current`, and returns the\n * new state.\n *\n * @throws `Error` when `event` is not permitted from the current state.\n */\n transition(event: RecordEvent): RecordState {\n const next = TABLE[this.current][event];\n if (!next) {\n throw new Error(\n `Invalid transition: event \"${event}\" not allowed from state \"${this.current}\"`,\n );\n }\n this.current = next;\n return next;\n }\n}\n","/**\n * Immutable point-in-time view of a model record.\n *\n * A `Snapshot` is created immediately before an adapter call so that adapter\n * and serializer code reads a consistent, frozen picture of the record\n * regardless of mutations that happen after the call begins.\n *\n * Key guarantees:\n * - Attribute data is copied at construction time; later record mutations do\n * not bleed into the snapshot.\n * - Relationship data is captured via a `Map` copy for the same reason.\n * - `changedAttributes()` compares the snapshot-time data against the\n * record's original (server-received) data, not the current live state.\n * - `eachAttribute` / `eachRelationship` iterate the merged schema definitions\n * walked at construction from the prototype chain.\n */\n\nimport 'reflect-metadata';\nimport {\n ATTRIBUTES_META_KEY,\n RELATIONSHIPS_META_KEY,\n type AttributeDef,\n type RelationshipDef,\n} from '@mobx-data/schema';\nimport type { Model, RelationshipRef } from './Model.js';\n\n/** Shape of a serialised `belongsTo` reference as stored in a snapshot. */\nexport interface BelongsToReference {\n id: string | null;\n type: string;\n}\n\n/** Shape of a serialised `hasMany` item reference as stored in a snapshot. */\nexport interface HasManyReference {\n id: string;\n type: string;\n}\n\n/**\n * Walks the prototype chain from root to leaf, merging own-metadata entries\n * so that subclass definitions override parent definitions.\n */\nfunction walk<V>(proto: object | null, key: symbol): Map<string, V> {\n const chain: object[] = [];\n let current: object | null = proto;\n while (current && current !== Object.prototype) {\n chain.push(current);\n current = Object.getPrototypeOf(current);\n }\n const merged = new Map<string, V>();\n for (const entry of chain.reverse()) {\n const local = Reflect.getOwnMetadata(key, entry) as Map<string, V> | undefined;\n if (local) {\n for (const [name, meta] of local) {\n merged.set(name, meta);\n }\n }\n }\n return merged;\n}\n\nexport class Snapshot<T extends Model = Model> {\n /** Server-assigned id at snapshot time, or `null` for new records. */\n readonly id: string | null;\n /** `modelName` of the snapshotted record. */\n readonly modelName: string;\n /** Reference to the live record (read-only from adapter/serializer code). */\n readonly record: T;\n\n private readonly _attributes: Record<string, unknown>;\n private readonly _relationships: Map<string, RelationshipRef>;\n private readonly _changedAttributes: Record<string, [unknown, unknown]>;\n private readonly _attributeDefinitions: Map<string, AttributeDef>;\n private readonly _relationshipDefinitions: Map<string, RelationshipDef>;\n\n constructor(record: T) {\n this.record = record;\n this.id = record.id;\n this.modelName = record.modelName;\n\n const internal = record as unknown as {\n _data: Record<string, unknown>;\n _relationships: Map<string, RelationshipRef>;\n };\n // Freeze a copy so later record mutations don't bleed in.\n this._attributes = { ...internal._data };\n this._relationships = new Map(internal._relationships);\n this._changedAttributes = record.changedAttributes();\n\n const proto = Object.getPrototypeOf(record) as object;\n this._attributeDefinitions = walk<AttributeDef>(proto, ATTRIBUTES_META_KEY);\n this._relationshipDefinitions = walk<RelationshipDef>(proto, RELATIONSHIPS_META_KEY);\n }\n\n /** Returns the snapshot-time value for an attribute key. */\n attr<K extends keyof T>(key: K): T[K] {\n return this._attributes[key as string] as T[K];\n }\n\n /**\n * Returns the `belongsTo` reference for `key`.\n * When `{ id: true }` is passed, returns only the id string; otherwise\n * returns a `BelongsToReference` `{ id, type }` object, or `null` when the\n * relationship is empty.\n */\n belongsTo(\n key: string,\n options?: { id: boolean },\n ): BelongsToReference | string | null {\n const relationship = this._relationships.get(key);\n if (!relationship || relationship.data === null) {\n return null;\n }\n const data = relationship.data as { id: string; type: string };\n if (options?.id) {\n return data.id;\n }\n return { id: data.id, type: data.type };\n }\n\n /**\n * Returns the `hasMany` references for `key`.\n * When `{ ids: true }` is passed, returns a plain string array of ids;\n * otherwise returns an array of `HasManyReference` objects.\n */\n hasMany(\n key: string,\n options?: { ids: boolean },\n ): HasManyReference[] | string[] {\n const relationship = this._relationships.get(key);\n if (!relationship || !Array.isArray(relationship.data)) {\n return [];\n }\n const list = relationship.data as Array<{ id: string; type: string }>;\n if (options?.ids) {\n return list.map((reference) => reference.id);\n }\n return list.map((reference) => ({ id: reference.id, type: reference.type }));\n }\n\n /**\n * Returns a `{ [key]: [original, current] }` map of attributes that\n * differ from the server-received values at snapshot time.\n */\n changedAttributes(): Record<string, [unknown, unknown]> {\n return { ...this._changedAttributes };\n }\n\n /** Iterates over every attribute definition, calling `callback` for each. */\n eachAttribute(callback: (key: string, meta: AttributeDef) => void): void {\n for (const [key, meta] of this._attributeDefinitions) {\n callback(key, meta);\n }\n }\n\n /** Iterates over every relationship definition, calling `callback` for each. */\n eachRelationship(callback: (key: string, meta: RelationshipDef) => void): void {\n for (const [key, meta] of this._relationshipDefinitions) {\n callback(key, meta);\n }\n }\n}\n","/**\n * Base class for all mobx-data model records.\n *\n * `Model` is an abstract MobX-observable class that manages the complete\n * lifecycle of a server-side resource. Subclasses declare their schema using\n * `@attr`, `@belongsTo`, and `@hasMany` decorators; `Model` automatically\n * installs observable getters/setters for each declaration the first time the\n * class is instantiated.\n *\n * ## State machine\n * Every record progresses through the states tracked by `StateMachine`:\n * - **empty** → initial placeholder state\n * - **loading** → adapter request in flight\n * - **loaded.saved** → clean, persisted record\n * - **loaded.created.uncommitted** → new, unsaved record\n * - **loaded.updated.uncommitted** → dirty, unsaved changes\n * - **deleted.*** → record marked for / undergoing deletion\n * - **error** → adapter threw a non-validation error\n *\n * ## Lifecycle hooks\n * Override `didLoad`, `didCreate`, `didUpdate`, `didDelete`, `willSave`,\n * `didSave`, `becameInvalid`, and `becameError` to react to state transitions.\n *\n * ## Store integration\n * Records are normally created and loaded through a `Store` instance. The\n * `store` property is set by the store after instantiation so that `save()`,\n * `reload()`, and `destroyRecord()` can delegate back to it.\n */\n\nimport 'reflect-metadata';\nimport {\n makeObservable,\n observable,\n computed,\n action,\n runInAction,\n} from 'mobx';\nimport {\n ATTRIBUTES_META_KEY,\n RELATIONSHIPS_META_KEY,\n type AttributeDef,\n type RelationshipDef,\n} from '@mobx-data/schema';\nimport { Errors } from './Errors.js';\nimport { StateMachine, type RecordState, type RecordEvent } from './StateMachine.js';\nimport { Snapshot } from './Snapshot.js';\n\n/**\n * Raw relationship reference stored on the record.\n * Contains either a single `{ type, id }` object (belongsTo),\n * an array of them (hasMany), or `null`.\n */\nexport interface RelationshipRef {\n data:\n | { type: string; id: string }\n | Array<{ type: string; id: string }>\n | null;\n}\n\n/**\n * Minimal store interface that `Model` uses to delegate persistence operations.\n * The full `Store` class satisfies this interface.\n */\nexport interface SaveOptions {\n patch?: boolean;\n adapterOptions?: Record<string, unknown>;\n}\n\nexport interface ModelStoreLike {\n saveRecord?<T extends Model>(record: T, options?: SaveOptions): Promise<T>;\n deleteRecord?<T extends Model>(record: T): Promise<T>;\n reloadRecord?<T extends Model>(record: T): Promise<T>;\n unloadRecord?(record: Model): void;\n peekRecord?<T extends Model = Model>(type: string, id: string): T | null;\n findRecord?<T extends Model = Model>(\n type: string,\n id: string,\n options?: unknown,\n ): Promise<T>;\n onRelationshipSet?(\n record: Model,\n relName: string,\n ref: RelationshipRef,\n ): void;\n resolveRelationship?(\n record: Model,\n name: string,\n meta: RelationshipDef,\n ): unknown;\n setRelationshipValue?(\n record: Model,\n name: string,\n meta: RelationshipDef,\n value: unknown,\n ): void;\n}\n\n/** Options accepted by the `Model` constructor. */\nexport interface ModelConstructorOptions {\n /** Server-assigned id, or `null` / `undefined` for new records. */\n id?: string | null;\n /** Initial attribute data. */\n data?: Record<string, unknown>;\n /** Initial relationship references. */\n relationships?: Record<string, RelationshipRef>;\n /** Store instance injected so records can delegate persistence. */\n store?: ModelStoreLike;\n}\n\n/** Options accepted by the static `Model.push` factory method. */\nexport interface PushOptions {\n id: string;\n data: Record<string, unknown>;\n relationships?: Record<string, RelationshipRef>;\n store?: ModelStoreLike;\n}\n\n/** Internal constructor options that include the initial state override. */\ninterface InternalOptions extends ModelConstructorOptions {\n __initialState?: RecordState;\n}\n\n/** Symbol used as a per-class flag to avoid reinstalling accessors. */\nconst ACCESSORS_INSTALLED = Symbol('mobx-data:accessors-installed');\n\n/**\n * Walks the prototype chain from root to leaf and merges own-metadata\n * entries, with subclass definitions overriding ancestors.\n */\nfunction walkProto<V>(\n proto: object | null,\n metadataKey: symbol,\n): Map<string, V> {\n const chain: object[] = [];\n let current: object | null = proto;\n while (current && current !== Object.prototype) {\n chain.push(current);\n current = Object.getPrototypeOf(current);\n }\n const merged = new Map<string, V>();\n for (const entry of chain.reverse()) {\n const local = Reflect.getOwnMetadata(metadataKey, entry) as\n | Map<string, V>\n | undefined;\n if (local) {\n for (const [name, value] of local) {\n merged.set(name, value);\n }\n }\n }\n return merged;\n}\n\n/**\n * Installs observable getters/setters on the class prototype for every\n * `@attr` and `@belongsTo` / `@hasMany` declaration.\n *\n * Run once per class (guarded by `ACCESSORS_INSTALLED`); subsequent\n * instantiations are a no-op.\n */\nfunction ensureAccessorsInstalled(klass: Function): void {\n const proto = klass.prototype as Record<PropertyKey, unknown> & {\n [ACCESSORS_INSTALLED]?: boolean;\n };\n if ((klass as unknown as Record<symbol, unknown>)[ACCESSORS_INSTALLED]) {\n return;\n }\n (klass as unknown as Record<symbol, unknown>)[ACCESSORS_INSTALLED] = true;\n\n const attrs = walkProto<AttributeDef>(proto as object, ATTRIBUTES_META_KEY);\n for (const [name] of attrs) {\n Object.defineProperty(proto, name, {\n get(this: Model) {\n return (this as unknown as { _data: Record<string, unknown> })._data[name];\n },\n set(this: Model, value: unknown) {\n (this as unknown as { _setAttribute(k: string, v: unknown): void })._setAttribute(\n name,\n value,\n );\n },\n configurable: true,\n enumerable: true,\n });\n }\n\n const relationships = walkProto<RelationshipDef>(proto as object, RELATIONSHIPS_META_KEY);\n for (const [name, meta] of relationships) {\n Object.defineProperty(proto, name, {\n get(this: Model) {\n return (this as unknown as {\n _resolveRelationship(name: string, meta: RelationshipDef): unknown;\n })._resolveRelationship(name, meta);\n },\n set(this: Model, value: unknown) {\n (this as unknown as {\n _setRelationship(name: string, meta: RelationshipDef, value: unknown): void;\n })._setRelationship(name, meta, value);\n },\n configurable: true,\n enumerable: true,\n });\n }\n}\n\nexport abstract class Model {\n /** Registered model name — must be set as a static property on subclasses. */\n static modelName: string;\n\n /**\n * Factory method that creates an instance in the `root.loaded.saved` state\n * (i.e. as if freshly loaded from the server) and calls `didLoad()`.\n *\n * Used internally by `Store.pushResource` to avoid exposing the internal\n * `__initialState` option.\n */\n static push<T extends typeof Model>(\n this: T,\n opts: PushOptions,\n ): InstanceType<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const Klass = this as unknown as new (internalOpts: InternalOptions) => Model;\n const instance = new Klass({\n ...opts,\n __initialState: 'root.loaded.saved',\n });\n (instance as unknown as { didLoad(): void }).didLoad();\n return instance as InstanceType<T>;\n }\n\n // --- internal reactive state (prefixed with _) ---\n\n /** Current attribute values. Deep-observable so nested mutations are tracked. */\n protected _data: Record<string, unknown> = {};\n /** Snapshot of attribute values as last received from the server (dirty tracking baseline). */\n protected _originalData: Record<string, unknown> = {};\n /** Raw relationship references keyed by relationship name. */\n protected _relationships: Map<string, RelationshipRef> = new Map();\n /** Server-assigned id, or `null` for new records. */\n protected _id: string | null = null;\n /** Internal lifecycle state machine. */\n protected _stateMachine: StateMachine;\n\n /** Observable validation error collection. */\n readonly errors: Errors = new Errors();\n /** Reference to the owning store, injected at construction. */\n store?: ModelStoreLike;\n\n constructor(options: ModelConstructorOptions = {}) {\n const opts = options as InternalOptions;\n ensureAccessorsInstalled(this.constructor);\n\n this._id = opts.id ?? null;\n this.store = opts.store;\n this._stateMachine = new StateMachine(\n opts.__initialState ?? 'root.loaded.created.uncommitted',\n );\n\n const initialData = opts.data ? { ...opts.data } : {};\n this._data = initialData;\n // When pushed (clean), snapshot original for dirty tracking.\n if (opts.__initialState === 'root.loaded.saved') {\n this._originalData = { ...initialData };\n } else {\n this._originalData = {};\n }\n\n if (opts.relationships) {\n for (const [name, reference] of Object.entries(opts.relationships)) {\n this._relationships.set(name, reference);\n }\n }\n\n makeObservable<\n this,\n | '_data'\n | '_originalData'\n | '_relationships'\n | '_id'\n | '_setAttribute'\n | '_transitionIfClean'\n | '_applyServerData'\n | '_setState'\n >(this, {\n _data: observable.shallow,\n _originalData: observable.ref,\n _relationships: observable.shallow,\n _id: observable,\n id: computed,\n currentState: computed,\n isLoading: computed,\n isLoaded: computed,\n isSaving: computed,\n isDirty: computed,\n hasDirtyAttributes: computed,\n isNew: computed,\n isDeleted: computed,\n isValid: computed,\n isError: computed,\n isEmpty: computed,\n _setAttribute: action,\n _transitionIfClean: action,\n _applyServerData: action,\n _setState: action,\n rollbackAttributes: action,\n deleteRecord: action,\n });\n }\n\n /** Server-assigned id, or `null` for new records. */\n get id(): string | null {\n return this._id;\n }\n\n set id(v: string | null) {\n runInAction(() => {\n this._id = v;\n });\n }\n\n /** Returns the static `modelName` from the concrete subclass constructor. */\n get modelName(): string {\n return (this.constructor as typeof Model).modelName;\n }\n\n /** Current state-machine state string. */\n get currentState(): RecordState {\n return this._stateMachine.current;\n }\n\n /** `true` while an adapter request to fetch this record is in flight. */\n get isLoading(): boolean {\n return this.currentState === 'root.loading';\n }\n\n /** `true` when the record has been loaded (any `root.loaded.*` state). */\n get isLoaded(): boolean {\n return this.currentState.startsWith('root.loaded');\n }\n\n /** `true` while a create or update request is in flight. */\n get isSaving(): boolean {\n return this.currentState.endsWith('.inFlight');\n }\n\n /** `true` when the record was created locally and has never been saved. */\n get isNew(): boolean {\n return this.currentState.startsWith('root.loaded.created');\n }\n\n /** `true` when `deleteRecord()` has been called (regardless of server state). */\n get isDeleted(): boolean {\n return this.currentState.startsWith('root.deleted');\n }\n\n /** `true` when the record is in the `root.error` state. */\n get isError(): boolean {\n return this.currentState === 'root.error';\n }\n\n /** `true` when the record is in the `root.empty` placeholder state. */\n get isEmpty(): boolean {\n return this.currentState === 'root.empty';\n }\n\n /** `true` when any attribute differs from its last-saved value. */\n get hasDirtyAttributes(): boolean {\n const data = this._data;\n const original = this._originalData;\n for (const key of Object.keys(data)) {\n if (!Object.is(data[key], original[key])) {\n return true;\n }\n }\n for (const key of Object.keys(original)) {\n if (!(key in data)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * `true` when the record needs to be saved — new, deleted (not yet\n * confirmed), or has dirty attributes.\n */\n get isDirty(): boolean {\n if (this.isNew) {\n return true;\n }\n if (this.isDeleted && this.currentState !== 'root.deleted.saved') {\n return true;\n }\n return this.hasDirtyAttributes;\n }\n\n /** `true` when `errors.isEmpty` — i.e. no validation errors are present. */\n get isValid(): boolean {\n return this.errors.isEmpty;\n }\n\n /**\n * Returns a `{ [key]: [original, current] }` map of attributes that differ\n * from the last server-received snapshot.\n */\n changedAttributes(): Record<string, [unknown, unknown]> {\n const changed: Record<string, [unknown, unknown]> = {};\n const keys = new Set([\n ...Object.keys(this._data),\n ...Object.keys(this._originalData),\n ]);\n for (const key of keys) {\n const current = this._data[key];\n const original = this._originalData[key];\n if (!Object.is(current, original)) {\n changed[key] = [original, current];\n }\n }\n return changed;\n }\n\n /**\n * Resets all attributes to their original server values and clears\n * validation errors. For new records the record is transitioned to\n * `root.empty` and unloaded from the store.\n */\n rollbackAttributes(): void {\n this._data = { ...this._originalData };\n this.errors.clear();\n if (this.isNew) {\n this._setState('root.empty');\n if (this.store?.unloadRecord) {\n this.store.unloadRecord(this);\n }\n return;\n }\n if (this.currentState === 'root.loaded.updated.uncommitted') {\n this._stateMachine.transition('rolledBack');\n } else if (this.currentState === 'root.deleted.uncommitted') {\n this._stateMachine.transition('rolledBack');\n }\n }\n\n /**\n * Persists the record to the server. No-ops if the record is not dirty.\n * Delegates to `store.saveRecord`.\n *\n * @throws when no store is attached.\n */\n async save(\n options: SaveOptions = {},\n ): Promise<this> {\n if (!this.isDirty) {\n return this;\n }\n if (!this.store?.saveRecord) {\n throw new Error('Cannot save: no store attached');\n }\n const wasNew = this.isNew;\n this.willSave();\n this._stateMachine.transition('willCommit');\n try {\n await this.store.saveRecord(this, options);\n // If the store didn't already finalize the record, do it here.\n if (\n this.currentState === 'root.loaded.created.inFlight'\n || this.currentState === 'root.loaded.updated.inFlight'\n ) {\n runInAction(() => {\n this._originalData = { ...this._data };\n this._stateMachine.transition('didCommit');\n });\n }\n if (wasNew) {\n this.didCreate();\n } else {\n this.didUpdate();\n }\n this.didSave();\n return this;\n } catch (error) {\n if (!this.errors.isEmpty) {\n this._stateMachine.transition('becameInvalid');\n this.becameInvalid();\n } else {\n this._stateMachine.transition('becameError');\n this.becameError();\n }\n throw error;\n }\n }\n\n /**\n * Reloads the record from the server.\n * @throws when no store is attached.\n */\n async reload(): Promise<this> {\n if (!this.store?.reloadRecord) {\n throw new Error('Cannot reload: no store attached');\n }\n return (await this.store.reloadRecord(this)) as this;\n }\n\n /**\n * Marks the record for deletion. The record moves to\n * `root.deleted.uncommitted` but is not yet removed from the server.\n * Call `destroyRecord()` to also issue the DELETE request.\n */\n deleteRecord(): void {\n if (this.isNew) {\n this._setState('root.deleted.uncommitted');\n } else {\n this._stateMachine.transition('deleteRecord');\n }\n }\n\n /**\n * Marks the record for deletion and immediately sends a DELETE request.\n * @throws when no store is attached.\n */\n async destroyRecord(): Promise<this> {\n this.deleteRecord();\n if (!this.store?.deleteRecord) {\n throw new Error('Cannot destroy: no store attached');\n }\n this._stateMachine.transition('willCommit');\n const result = (await this.store.deleteRecord(this)) as this;\n if (this.currentState === 'root.deleted.inFlight') {\n this._stateMachine.transition('didCommit');\n }\n this.didDelete();\n return result;\n }\n\n /** Removes the record from the store's identity map without a server call. */\n unloadRecord(): void {\n if (this.store?.unloadRecord) {\n this.store.unloadRecord(this);\n }\n }\n\n /** Creates a frozen `Snapshot` of the current record state. */\n createSnapshot(): Snapshot<this> {\n return new Snapshot(this);\n }\n\n /** Returns a plain-object representation of the current attribute data. */\n serialize(_options: { includeId?: boolean } = {}): Record<string, unknown> {\n return { ...this._data };\n }\n\n /** Returns `{ id, ...attributes }` — used by `JSON.stringify`. */\n toJSON(): Record<string, unknown> {\n return { id: this._id, ...this._data };\n }\n\n // Lifecycle hooks — default no-ops, overridable.\n\n /** Called after the record is loaded from the server. */\n didLoad(): void {}\n /** Called after a new record is successfully persisted. */\n didCreate(): void {}\n /** Called after an existing record is successfully updated. */\n didUpdate(): void {}\n /** Called after a record is successfully deleted. */\n didDelete(): void {}\n /** Called immediately before a save request is issued. */\n willSave(): void {}\n /** Called after any successful save (create or update). */\n didSave(): void {}\n /** Called when the server returns a 422-style validation error. */\n becameInvalid(): void {}\n /** Called when the server returns a non-validation error. */\n becameError(): void {}\n\n // --- internals ---\n\n /** Called by generated attribute setters. */\n protected _setAttribute(key: string, value: unknown): void {\n if (Object.is(this._data[key], value)) {\n return;\n }\n this._data[key] = value;\n this._transitionIfClean();\n }\n\n /**\n * Transitions to `updated.uncommitted` when the record becomes dirty, or\n * back to `saved` when all changes are rolled back.\n */\n protected _transitionIfClean(): void {\n const dirty = this.hasDirtyAttributes;\n if (dirty && this.currentState === 'root.loaded.saved') {\n this._stateMachine.transition('didSetProperty');\n } else if (!dirty && this.currentState === 'root.loaded.updated.uncommitted') {\n this._stateMachine.transition('rolledBack');\n }\n }\n\n /** Directly sets the state machine's current state (bypasses transition validation). */\n protected _setState(state: RecordState): void {\n this._stateMachine.current = state;\n }\n\n /** Fires a state-machine transition event. */\n protected _transition(event: RecordEvent): void {\n this._stateMachine.transition(event);\n }\n\n /** Used by Store to apply server data after save, making record clean again. */\n protected _applyServerData(\n id: string | null,\n data: Record<string, unknown>,\n relationships?: Record<string, RelationshipRef>,\n ): void {\n if (id !== null) {\n this._id = id;\n }\n this._data = { ...this._data, ...data };\n this._originalData = { ...this._data };\n this.errors.clear();\n if (relationships) {\n for (const [name, reference] of Object.entries(relationships)) {\n this._relationships.set(name, reference);\n }\n }\n if (this.currentState === 'root.loaded.created.inFlight') {\n this._stateMachine.transition('didCommit');\n this.didCreate();\n } else if (this.currentState === 'root.loaded.updated.inFlight') {\n this._stateMachine.transition('didCommit');\n this.didUpdate();\n } else if (this.currentState === 'root.deleted.inFlight') {\n this._stateMachine.transition('didCommit');\n } else if (this.currentState === 'root.loading') {\n this._stateMachine.transition('pushedData');\n }\n // If pushed externally to a created/updated record, reset to saved.\n if (\n !this.isNew\n && !this.isDeleted\n && (this.currentState === 'root.loaded.updated.uncommitted'\n || this.currentState === 'root.loaded.created.uncommitted')\n ) {\n this._setState('root.loaded.saved');\n }\n }\n\n /** Relationship data (reference only). Resolution to records lives in Store. */\n protected _getRelationshipRef(name: string): RelationshipRef | null {\n return this._relationships.get(name) ?? null;\n }\n\n /** Stores a raw relationship reference without triggering store logic. */\n protected _setRelationshipRef(name: string, ref: RelationshipRef): void {\n this._relationships.set(name, ref);\n }\n\n /**\n * Delegates relationship resolution to the store.\n * Returns `null` when no store is attached (e.g. in unit tests).\n */\n protected _resolveRelationship(\n name: string,\n meta: RelationshipDef,\n ): unknown {\n if (this.store?.resolveRelationship) {\n return this.store.resolveRelationship(this, name, meta);\n }\n return null;\n }\n\n /** Delegates relationship mutation to the store (which also handles inverse sync). */\n protected _setRelationship(\n name: string,\n meta: RelationshipDef,\n value: unknown,\n ): void {\n if (this.store?.setRelationshipValue) {\n this.store.setRelationshipValue(this, name, meta, value);\n }\n }\n}\n","/**\n * Relationship proxy classes returned by relationship getters on Model instances.\n *\n * Three classes are exported:\n *\n * - `ManyArray<T>` — a synchronous, MobX-observable live view of a `hasMany`\n * relationship. Its contents are resolved directly from the store's identity\n * map on each access, so it stays in sync automatically as records are\n * pushed, unloaded, or added/removed via `push` / `removeObject`.\n *\n * - `AsyncBelongsTo<T>` — a `PromiseLike` wrapper for a `belongsTo` that\n * may need to be fetched from the server. Supports `await`, `then`, and\n * MobX-observable state flags (`isLoading`, `isLoaded`, `isFulfilled`,\n * `isRejected`, `value`).\n *\n * - `AsyncHasMany<T>` — same semantics as `AsyncBelongsTo` but resolves to a\n * `ManyArray<T>` instead of a single record.\n *\n * Both async wrappers eagerly check the store cache on construction; if all\n * referenced records are already present they transition to `fulfilled`\n * without issuing any network requests.\n */\n\nimport {\n makeObservable, observable, computed, action, runInAction,\n} from 'mobx';\nimport type { RelationshipDef } from '@mobx-data/schema';\nimport type { Model, ModelStoreLike, RelationshipRef } from './Model.js';\n\n/** Context object shared by all relationship proxy classes. */\nexport interface RelationshipHost {\n /** The record that owns the relationship. */\n parent: Model;\n /** Name of the relationship property on the owner. */\n name: string;\n /** Relationship definition from the schema. */\n meta: RelationshipDef;\n /** Store instance used to peek / find related records. */\n store: RelationshipCapableStore;\n}\n\n/**\n * Extended store interface required by the relationship proxy classes.\n * `Store` satisfies this interface.\n */\nexport interface RelationshipCapableStore extends ModelStoreLike {\n peekRecord<T extends Model = Model>(type: string, id: string): T | null;\n findRecord<T extends Model = Model>(\n type: string,\n id: string,\n options?: unknown,\n ): Promise<T>;\n _getRelationshipRefFor(record: Model, name: string): RelationshipRef | null;\n _getPendingMembers(record: Model, name: string): Iterable<Model>;\n _hasManyAppend(record: Model, name: string, meta: RelationshipDef, value: Model): void;\n _hasManyRemove(record: Model, name: string, meta: RelationshipDef, value: Model): void;\n}\n\n/**\n * Synchronous, live-updating array proxy for a `hasMany` relationship.\n *\n * Each access to `length`, iteration, or mutation goes through the store so\n * the array always reflects the current identity map state. Records that\n * have been `push`ed to the relationship but not yet assigned a server id\n * are tracked separately as \"pending members\" and are included in the\n * resolved list.\n */\nexport class ManyArray<T extends Model = Model> implements Iterable<T> {\n static refData(\n ref: RelationshipRef | null,\n ): Array<{ type: string; id: string }> {\n if (!ref || !ref.data) {\n return [];\n }\n return Array.isArray(ref.data) ? ref.data : [];\n }\n\n private host: RelationshipHost;\n\n constructor(host: RelationshipHost) {\n this.host = host;\n makeObservable<this, 'resolved'>(this, {\n resolved: computed,\n length: computed,\n push: action,\n removeObject: action,\n });\n }\n\n /**\n * Resolves the current set of related records from the store identity map.\n * Pending (unsaved) members appended via `push()` are appended at the end.\n */\n private get resolved(): T[] {\n const ref = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);\n const resolved: T[] = [];\n const seen = new Set<T>();\n for (const reference of ManyArray.refData(ref)) {\n const record = this.host.store.peekRecord<T>(reference.type, reference.id);\n if (record) {\n resolved.push(record);\n seen.add(record);\n }\n }\n const pending = this.host.store._getPendingMembers(\n this.host.parent,\n this.host.name,\n );\n for (const pendingRecord of pending as Iterable<T>) {\n if (!seen.has(pendingRecord)) {\n resolved.push(pendingRecord);\n }\n }\n return resolved;\n }\n\n /** Number of related records currently in the array. */\n get length(): number {\n return this.resolved.length;\n }\n\n /** Returns the record at `index`, or `undefined`. */\n at(index: number): T | undefined {\n return this.resolved[index];\n }\n\n /**\n * Adds one or more records to the relationship.\n * Delegates to `store._hasManyAppend` which also handles inverse tracking.\n */\n push(...records: T[]): number {\n for (const record of records) {\n this.host.store._hasManyAppend(\n this.host.parent,\n this.host.name,\n this.host.meta,\n record,\n );\n }\n return this.length;\n }\n\n /**\n * Removes a record from the relationship.\n * Delegates to `store._hasManyRemove` which also handles inverse tracking.\n */\n removeObject(record: T): void {\n this.host.store._hasManyRemove(\n this.host.parent,\n this.host.name,\n this.host.meta,\n record,\n );\n }\n\n /** Returns `true` when `record` is currently in the relationship. */\n includes(record: T): boolean {\n return this.resolved.includes(record);\n }\n\n /** Returns a plain array snapshot of all related records. */\n toArray(): T[] {\n return [...this.resolved];\n }\n\n /** Maps over the related records. */\n map<R>(callback: (record: T, i: number) => R): R[] {\n return this.resolved.map(callback);\n }\n\n /** Filters the related records. */\n filter(predicate: (record: T, i: number) => boolean): T[] {\n return this.resolved.filter(predicate);\n }\n\n /** Iterates over the related records. */\n forEach(callback: (record: T, i: number) => void): void {\n this.resolved.forEach(callback);\n }\n\n [Symbol.iterator](): Iterator<T> {\n return this.resolved[Symbol.iterator]();\n }\n}\n\n/**\n * Async wrapper for a `belongsTo` relationship.\n *\n * Implements `PromiseLike<T | null>` so it can be `await`ed. Also exposes\n * MobX-observable state flags:\n * - `isPending` / `isFulfilled` / `isRejected` — promise lifecycle\n * - `isLoading` — a network request is currently in flight\n * - `isLoaded` — the relationship has been resolved (even to `null`)\n * - `value` — the resolved record, or `null`\n * - `reason` — the rejection error, if any\n *\n * Eagerly checks the store cache at construction; if the referenced record is\n * already present it transitions straight to `fulfilled`.\n */\nexport class AsyncBelongsTo<T extends Model = Model>\nimplements PromiseLike<T | null> {\n private host: RelationshipHost;\n\n private loadedState: 'pending' | 'fulfilled' | 'rejected' = 'pending';\n\n private currentValue: T | null = null;\n\n private error: unknown = null;\n\n private inflight: Promise<T | null> | null = null;\n\n constructor(host: RelationshipHost) {\n this.host = host;\n makeObservable<this, 'loadedState' | 'currentValue' | 'error' | 'syncFromCache'>(this, {\n loadedState: observable,\n currentValue: observable.ref,\n error: observable.ref,\n isPending: computed,\n isFulfilled: computed,\n isRejected: computed,\n isLoaded: computed,\n isLoading: computed,\n value: computed,\n reason: computed,\n syncFromCache: action,\n });\n this.syncFromCache();\n }\n\n /** Checks the store cache and transitions to `fulfilled` if the record is already loaded. */\n private syncFromCache(): void {\n const ref = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);\n if (!ref || !ref.data || Array.isArray(ref.data)) {\n this.currentValue = null;\n this.loadedState = 'fulfilled';\n return;\n }\n const cached = this.host.store.peekRecord<T>(ref.data.type, ref.data.id);\n if (cached) {\n this.currentValue = cached;\n this.loadedState = 'fulfilled';\n }\n }\n\n /** `true` while the relationship has not yet been resolved. */\n get isPending(): boolean {\n return this.loadedState === 'pending';\n }\n\n /** `true` once the relationship has been resolved (including to `null`). */\n get isFulfilled(): boolean {\n return this.loadedState === 'fulfilled';\n }\n\n /** `true` if the network request failed. */\n get isRejected(): boolean {\n return this.loadedState === 'rejected';\n }\n\n /** `true` while a network request is in flight. */\n get isLoading(): boolean {\n return this.inflight !== null && this.isPending;\n }\n\n /** `true` once the relationship is resolved. */\n get isLoaded(): boolean {\n return this.loadedState === 'fulfilled';\n }\n\n /** The resolved record, or `null` when the relationship is empty or not yet loaded. */\n get value(): T | null {\n return this.currentValue;\n }\n\n /** The rejection reason if `isRejected`. */\n get reason(): unknown {\n return this.error;\n }\n\n /**\n * Ensures the related record is loaded, returning a `Promise<T | null>`.\n * If the record is already in the store it resolves immediately.\n * Concurrent calls share the same in-flight promise.\n */\n load(): Promise<T | null> {\n // Re-check cache each time in case it was populated externally.\n this.syncFromCache();\n if (this.loadedState === 'fulfilled' && this.currentValue) {\n return Promise.resolve(this.currentValue);\n }\n if (this.inflight) {\n return this.inflight;\n }\n const ref = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);\n if (!ref || !ref.data || Array.isArray(ref.data)) {\n return Promise.resolve(null);\n }\n const { type, id } = ref.data;\n this.inflight = this.host.store.findRecord<T>(type, id).then(\n (record) => {\n runInAction(() => {\n this.currentValue = record;\n this.loadedState = 'fulfilled';\n this.inflight = null;\n });\n return record;\n },\n (error) => {\n runInAction(() => {\n this.error = error;\n this.loadedState = 'rejected';\n this.inflight = null;\n });\n throw error;\n },\n );\n return this.inflight;\n }\n\n /** Forces a fresh fetch, ignoring any cached value. */\n reload(): Promise<T | null> {\n this.inflight = null;\n this.loadedState = 'pending';\n return this.load();\n }\n\n then<TResult1 = T | null, TResult2 = never>(\n onfulfilled?:\n | ((value: T | null) => TResult1 | PromiseLike<TResult1>)\n | null\n | undefined,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null\n | undefined,\n ): PromiseLike<TResult1 | TResult2> {\n return this.load().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * Async wrapper for a `hasMany` relationship.\n *\n * Mirrors the `AsyncBelongsTo` API but resolves to a `ManyArray<T>` instead\n * of a single record. Missing referenced records are fetched in parallel via\n * `store.findRecord`.\n */\nexport class AsyncHasMany<T extends Model = Model>\nimplements PromiseLike<ManyArray<T>> {\n private host: RelationshipHost;\n\n private manyArray: ManyArray<T>;\n\n private loadedState: 'pending' | 'fulfilled' | 'rejected' = 'pending';\n\n private error: unknown = null;\n\n private inflight: Promise<ManyArray<T>> | null = null;\n\n constructor(host: RelationshipHost) {\n this.host = host;\n this.manyArray = new ManyArray<T>(host);\n makeObservable<this, 'loadedState' | 'error' | 'syncFromCache'>(this, {\n loadedState: observable,\n error: observable.ref,\n isPending: computed,\n isFulfilled: computed,\n isRejected: computed,\n isLoaded: computed,\n isLoading: computed,\n length: computed,\n syncFromCache: action,\n });\n this.syncFromCache();\n }\n\n /** Transitions to `fulfilled` if all referenced records are already in the cache. */\n private syncFromCache(): void {\n const ref = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);\n const items = ManyArray.refData(ref);\n const allCached = items.every(\n (reference) => this.host.store.peekRecord(reference.type, reference.id) !== null,\n );\n if (allCached) {\n this.loadedState = 'fulfilled';\n }\n }\n\n /** `true` while the relationship has not yet been resolved. */\n get isPending(): boolean {\n return this.loadedState === 'pending';\n }\n\n /** `true` once all referenced records have been resolved. */\n get isFulfilled(): boolean {\n return this.loadedState === 'fulfilled';\n }\n\n /** `true` if any fetch failed. */\n get isRejected(): boolean {\n return this.loadedState === 'rejected';\n }\n\n /** `true` while a network request is in flight. */\n get isLoading(): boolean {\n return this.inflight !== null && this.isPending;\n }\n\n /** `true` once the relationship is resolved. */\n get isLoaded(): boolean {\n return this.loadedState === 'fulfilled';\n }\n\n /** The underlying `ManyArray` (always available, even before `load()`). */\n get value(): ManyArray<T> {\n return this.manyArray;\n }\n\n /** Number of records currently in the resolved array. */\n get length(): number {\n return this.manyArray.length;\n }\n\n /**\n * Ensures all referenced records are loaded.\n * Records already in the cache are not re-fetched.\n * Concurrent calls share the same in-flight promise.\n */\n load(): Promise<ManyArray<T>> {\n this.syncFromCache();\n if (this.loadedState === 'fulfilled') {\n return Promise.resolve(this.manyArray);\n }\n if (this.inflight) {\n return this.inflight;\n }\n const ref = this.host.store._getRelationshipRefFor(this.host.parent, this.host.name);\n const items = ManyArray.refData(ref);\n const missing = items.filter(\n (reference) => this.host.store.peekRecord(reference.type, reference.id) === null,\n );\n const loads = missing.map(\n (reference) => this.host.store.findRecord(reference.type, reference.id),\n );\n this.inflight = Promise.all(loads).then(\n () => {\n runInAction(() => {\n this.loadedState = 'fulfilled';\n this.inflight = null;\n });\n return this.manyArray;\n },\n (error) => {\n runInAction(() => {\n this.error = error;\n this.loadedState = 'rejected';\n this.inflight = null;\n });\n throw error;\n },\n );\n return this.inflight;\n }\n\n /** Forces a fresh fetch, ignoring any cached state. */\n reload(): Promise<ManyArray<T>> {\n this.inflight = null;\n this.loadedState = 'pending';\n return this.load();\n }\n\n then<TResult1 = ManyArray<T>, TResult2 = never>(\n onfulfilled?:\n | ((value: ManyArray<T>) => TResult1 | PromiseLike<TResult1>)\n | null\n | undefined,\n onrejected?:\n | ((reason: unknown) => TResult2 | PromiseLike<TResult2>)\n | null\n | undefined,\n ): PromiseLike<TResult1 | TResult2> {\n return this.load().then(onfulfilled, onrejected);\n }\n}\n"],"names":["Errors","makeObservable","observable","computed","action","total","messages","attribute","message","incoming","next","msg","entry","__decorateClass","injectable","TABLE","StateMachine","initial","event","walk","proto","key","chain","current","merged","local","name","meta","Snapshot","record","internal","ATTRIBUTES_META_KEY","RELATIONSHIPS_META_KEY","options","relationship","data","list","reference","callback","ACCESSORS_INSTALLED","walkProto","metadataKey","value","ensureAccessorsInstalled","klass","attrs","relationships","Model","opts","initialData","Klass","instance","v","runInAction","original","changed","keys","_a","wasNew","error","result","_options","dirty","state","id","ref","ManyArray","host","resolved","seen","pending","pendingRecord","index","records","predicate","AsyncBelongsTo","cached","type","onfulfilled","onrejected","AsyncHasMany","loads"],"mappings":"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"}
|