@warp-drive-mirror/experiments 5.10.0-alpha.1 → 5.10.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { n as RequestEventData, t as AbortEventData } from "./types-CRs-Qww6.js"
3
3
  import { CacheHandler as CacheHandler$1, Future } from "@warp-drive-mirror/core/request";
4
4
  import { Store } from "@warp-drive-mirror/core";
5
5
  //#region src/data-worker/worker.d.ts
6
- declare class DataWorker {
6
+ export declare class DataWorker {
7
7
  store: Store;
8
8
  threads: Map<string, MessagePort>;
9
9
  pending: Map<string, Map<number, Future<unknown>>>;
@@ -29,7 +29,6 @@ declare class DataWorker {
29
29
  * with their referenced resources.
30
30
  *
31
31
  */
32
- declare const CacheHandler: CacheHandler$1;
32
+ export declare const CacheHandler: CacheHandler$1;
33
33
  //#endregion
34
- export { CacheHandler, DataWorker };
35
34
  //# sourceMappingURL=data-worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-worker.d.ts","names":[],"sources":["../src/data-worker/worker.ts","../src/data-worker/cache-handler.ts"],"mappings":";;;;;cASa;EACX,OAAe;EACf,SAAiB,YAAY;EAC7B,SAAiB,YAAY,YAAY;EACzC;EACA;IAAmB;IAAoB;;EACvC,SAAiB;EAEjB,YAAY,kBAAkB,OAAO;IAAY;IAAoB;;EAarE;EAkCA,YAAY,gBAAgB,MAAM;EAqBlC,aAAa,OAAO;EAUpB,QAAc,OAAO,mBAAmB;;;;;;;;;cCnE7B,cAAc"}
1
+ {"version":3,"file":"data-worker.d.ts","names":[],"sources":["../src/data-worker/worker.ts","../src/data-worker/cache-handler.ts"],"mappings":";;;;;qBASa;EACX,OAAe;EACf,SAAiB,YAAY;EAC7B,SAAiB,YAAY,YAAY;EACzC;EACA;IAAmB;IAAoB;;EACvC,SAAiB;EAEjB,YAAY,kBAAkB,OAAO;IAAY;IAAoB;;EAarE;EAkCA,YAAY,gBAAgB,MAAM;EAqBlC,aAAa,OAAO;EAUpB,QAAc,OAAO,mBAAmB;;;;;;;;;qBCnE7B,cAAc"}
@@ -21,7 +21,7 @@ type RequestEventData = {
21
21
  *
22
22
  * @public
23
23
  */
24
- declare class ImageFetch {
24
+ export declare class ImageFetch {
25
25
  worker: Worker | SharedWorker;
26
26
  threadId: string;
27
27
  pending: Map<string, Deferred<string>>;
@@ -56,5 +56,4 @@ declare class ImageFetch {
56
56
  load(url: string): Promise<string>;
57
57
  }
58
58
  //#endregion
59
- export { ImageFetch };
60
59
  //# sourceMappingURL=image-fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image-fetch.d.ts","names":[],"sources":["../src/image-worker/types.ts","../src/image-worker/fetch.ts"],"mappings":";;;KA8BY;EACV;EACA;EACA;;;;;;;;;;;;;;;;;cCFW;EACX,QAAgB,SAAS;EACzB;EACA,SAAiB,YAAY;EAC7B,SAAiB;EACjB,OAAe;;;;;;EAOf,YAAY,QAAQ,SAAS;EA0C7B,eAAe,cAAc;EAO7B,MAAM,OAAO;;;;;;;;;;;;;;;;;;;EAuBb,KAAK,cAAc"}
1
+ {"version":3,"file":"image-fetch.d.ts","names":[],"sources":["../src/image-worker/types.ts","../src/image-worker/fetch.ts"],"mappings":";;;KA8BY;EACV;EACA;EACA;;;;;;;;;;;;;;;;;qBCFW;EACX,QAAgB,SAAS;EACzB;EACA,SAAiB,YAAY;EAC7B,SAAiB;EACjB,OAAe;;;;;;EAOf,YAAY,QAAQ,SAAS;EA0C7B,eAAe,cAAc;EAO7B,MAAM,OAAO;;;;;;;;;;;;;;;;;;;EAuBb,KAAK,cAAc"}
@@ -18,7 +18,7 @@
18
18
  *
19
19
  * @public
20
20
  */
21
- declare class ImageWorker {
21
+ export declare class ImageWorker {
22
22
  private threads;
23
23
  private pendingImages;
24
24
  private options;
@@ -36,5 +36,4 @@ declare class ImageWorker {
36
36
  private request;
37
37
  }
38
38
  //#endregion
39
- export { ImageWorker };
40
39
  //# sourceMappingURL=image-worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image-worker.d.ts","names":[],"sources":["../src/image-worker/worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;cA+Ba;UACK;UACA;UACA;UACA;UACA;;;;EAKhB,YAAY;IAAY;;UAahB;UAsBA;UA4BA;UAiBM"}
1
+ {"version":3,"file":"image-worker.d.ts","names":[],"sources":["../src/image-worker/worker.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;qBA+Ba;UACK;UACA;UACA;UACA;UACA;;;;EAKhB,YAAY;IAAY;;UAahB;UAsBA;UA4BA;UAiBM"}
package/dist/storage.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  //#region src/storage/cache.d.ts
2
- declare const DEFAULT_CACHE_ID = "reactive-cache";
3
- interface InternalCacheStorageEvent {
2
+ export declare const DEFAULT_CACHE_ID = "reactive-cache";
3
+ export interface InternalCacheStorageEvent {
4
4
  storageArea: string;
5
5
  key: string | null;
6
6
  oldValue: string | null;
7
7
  newValue: string | null;
8
8
  }
9
- interface CacheStorageEvent {
9
+ export interface CacheStorageEvent {
10
10
  storageArea: CacheStorage;
11
11
  key: string | null;
12
12
  oldValue: string | null;
@@ -18,7 +18,7 @@ interface CacheStorageEvent {
18
18
  * This is a good option for larger data sets than can be efficiently stored in localStorage
19
19
  * but should not be used as a permanent DB or storage solution.
20
20
  */
21
- declare class CacheStorage implements Storage {
21
+ export declare class CacheStorage implements Storage {
22
22
  #private;
23
23
  _data: Map<string, string | null>;
24
24
  _nextUpdate: number | null;
@@ -44,7 +44,7 @@ declare class CacheStorage implements Storage {
44
44
  }
45
45
  //#endregion
46
46
  //#region src/storage/storage.d.ts
47
- interface ReactiveStorageOptions {
47
+ export interface ReactiveStorageOptions {
48
48
  /**
49
49
  * If true, falls back to in-memory storage when the underlying
50
50
  * storage is unavailable (e.g., private browsing mode).
@@ -66,20 +66,39 @@ interface ReactiveStorageOptions {
66
66
  *
67
67
  * If the instance does not already exist, it is created.
68
68
  */
69
- declare function getLocalStorage(): ReactiveStorage;
70
- declare function getSessionStorage(): ReactiveStorage;
71
- declare function getCacheStorage(namespace?: string | null): ReactiveStorage;
69
+ export declare function getLocalStorage(): ReactiveStorage;
70
+ export declare function getSessionStorage(): ReactiveStorage;
71
+ export declare function getCacheStorage(namespace?: string | null): ReactiveStorage;
72
72
  /**
73
73
  * Configure options for the localStorage singleton.
74
74
  * Must be called before getLocalStorage() is first invoked.
75
75
  */
76
- declare function configureLocalStorage(options: ReactiveStorageOptions): void;
76
+ export declare function configureLocalStorage(options: ReactiveStorageOptions): void;
77
77
  /**
78
78
  * Configure options for the sessionStorage singleton.
79
79
  * Must be called before getSessionStorage() is first invoked.
80
80
  */
81
- declare function configureSessionStorage(options: ReactiveStorageOptions): void;
82
- type EffectStorageEvent = CacheStorageEvent | StorageEvent;
81
+ export declare function configureSessionStorage(options: ReactiveStorageOptions): void;
82
+ export type EffectStorageEvent = CacheStorageEvent | StorageEvent;
83
+ /**
84
+ * Subscribes to storage-change events, whether they originate from the
85
+ * native Storage API (a `StorageEvent`, fired cross-tab) or from
86
+ * {@link CacheStorage}'s own same-tab notifications (dispatched as a
87
+ * `CustomEvent` under the same 'storage' name — see `emitStorageEvent`
88
+ * in `./cache.ts`).
89
+ *
90
+ * Returns an unsubscribe function.
91
+ *
92
+ * This can't be expressed by widening the global `WindowEventMap.storage`
93
+ * type: that entry is inherited from `WindowEventHandlersEventMap` as
94
+ * `StorageEvent`, and a declaration-merged override has to stay assignable
95
+ * to the type it's overriding, not the other way around — deliberately
96
+ * reusing this event name for a wider union has no way to satisfy that.
97
+ *
98
+ * Route storage-event subscribers through this helper instead of calling
99
+ * `window.addEventListener('storage', ...)` directly.
100
+ */
101
+ export declare function onStorageEvent(listener: (event: EffectStorageEvent) => void): () => void;
83
102
  /**
84
103
  * A reactive wrapper around the Web Storage API (localStorage/sessionStorage)
85
104
  * that provides signal-based access to storage items and length.
@@ -126,11 +145,11 @@ declare class ReactiveStorage implements Storage {
126
145
  key(index: number): string | null;
127
146
  }
128
147
  //#endregion
129
- //#region src/storage/-private/storage-infra.d.ts
148
+ //#region src/storage/query-params.d.ts
130
149
  /**
131
150
  * Configuration options for fields that are also query parameters
132
151
  */
133
- interface ParamConfig {
152
+ export interface ParamConfig {
134
153
  /**
135
154
  * Convert a value into a string for storage in the URL.
136
155
  * `null` indicates the value should be omitted from the URL.
@@ -152,6 +171,64 @@ interface ParamConfig {
152
171
  */
153
172
  getDefault?: (instance: any) => unknown;
154
173
  }
174
+ /**
175
+ * Creates a {@link ParamConfig} for boolean fields that serialize to '1' or null.
176
+ *
177
+ * @returns ParamConfig for boolean fields
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * @param(BooleanParam())
182
+ * @field
183
+ * myFlag: boolean = false;
184
+ * ```
185
+ */
186
+ export declare function BooleanParam(): ParamConfig;
187
+ /**
188
+ * Creates a {@link ParamConfig} for numeric fields with default value checking.
189
+ *
190
+ * @param precision - When given, the number of digits to serialize after the decimal point
191
+ * @param getDefault - Function to get the default value for comparison
192
+ * @returns ParamConfig for number fields
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * @param(NumberParam(2, function (instance: MyClass) { return instance.defaultZoom; }))
197
+ * @field
198
+ * zoom: number = 12;
199
+ * ```
200
+ */
201
+ export declare function NumberParam(precision?: number, getDefault?: (instance: any) => number | undefined): ParamConfig;
202
+ /**
203
+ * Decorator which marks a field as a query parameter.
204
+ *
205
+ * This decorator only stores metadata - it does not change the property behavior.
206
+ * The field will operate as a normal `@field` until a router integration consumes it.
207
+ *
208
+ * The provided {@link ParamConfig} is used to:
209
+ * - Serialize values for the URL
210
+ * - Deserialize values from the URL
211
+ * - Compare URL and local values
212
+ * - Determine when to include/exclude params from the URL
213
+ *
214
+ * @param config - Configuration for URL serialization/deserialization
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * @SessionResource('map-state')
219
+ * class MapState {
220
+ * @param({
221
+ * serialize: (value: unknown) => (value ? '1' : null),
222
+ * deserialize: (urlValue: string) => urlValue === '1',
223
+ * })
224
+ * @field
225
+ * active: boolean = false;
226
+ * }
227
+ * ```
228
+ */
229
+ export declare function param(config: ParamConfig): PropertyDecorator;
230
+ //#endregion
231
+ //#region src/storage/-private/storage-infra.d.ts
155
232
  interface InternalParamConfig extends ParamConfig {
156
233
  initialized?: boolean;
157
234
  }
@@ -227,7 +304,7 @@ declare function getParamCompanion(instance: object, groupControlMap?: Record<st
227
304
  * The function will be called once per instance during
228
305
  * initialization to determine the unique ID for that instance.
229
306
  */
230
- declare function LocalResource(id: string | KeyFn): ClassDecorator;
307
+ export declare function LocalResource(id: string | KeyFn): ClassDecorator;
231
308
  /**
232
309
  * Decorator which transforms a class into a StorageResource
233
310
  * persisted in sessionStorage.
@@ -242,7 +319,7 @@ declare function LocalResource(id: string | KeyFn): ClassDecorator;
242
319
  * The function will be called once per instance during
243
320
  * initialization to determine the unique ID for that instance.
244
321
  */
245
- declare function SessionResource(id: string | KeyFn): ClassDecorator;
322
+ export declare function SessionResource(id: string | KeyFn): ClassDecorator;
246
323
  /**
247
324
  * Decorator which transforms a class into a StorageResource
248
325
  * persisted via the [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache).
@@ -262,7 +339,7 @@ declare function SessionResource(id: string | KeyFn): ClassDecorator;
262
339
  * so partitioning can be achieved by using different namespaces for different groups
263
340
  * of data.
264
341
  */
265
- declare function CacheResource(id: string | KeyFn, namespace?: string | null): ClassDecorator;
342
+ export declare function CacheResource(id: string | KeyFn, namespace?: string | null): ClassDecorator;
266
343
  /**
267
344
  * Decorator which marks a property as a field on
268
345
  * a LocalResource or SessionResource
@@ -294,9 +371,9 @@ declare function CacheResource(id: string | KeyFn, namespace?: string | null): C
294
371
  * ```
295
372
  *
296
373
  */
297
- declare function field(type: "local" | "session" | "cache"): PropertyDecorator;
298
- declare function field(target: object, key: string, descriptor?: PropertyDescriptor): void;
299
- declare function input(type: "number" | "boolean" | "float"): PropertyDecorator;
374
+ export declare function field(type: "local" | "session" | "cache"): PropertyDecorator;
375
+ export declare function field(target: object, key: string, descriptor?: PropertyDescriptor): void;
376
+ export declare function input(type: "number" | "boolean" | "float"): PropertyDecorator;
300
377
  /**
301
378
  * Effects are fields that run a side-effecting function.
302
379
  *
@@ -348,7 +425,7 @@ declare function input(type: "number" | "boolean" | "float"): PropertyDecorator;
348
425
  * }
349
426
  * ```
350
427
  */
351
- declare function effect(fn: <K>(update: ValueTransition<K>) => void, type?: "local" | "session"): PropertyDecorator;
428
+ export declare function effect(fn: <K>(update: ValueTransition<K>) => void, type?: "local" | "session"): PropertyDecorator;
352
429
  //#endregion
353
- export { CacheResource, CacheStorage, CacheStorageEvent, DEFAULT_CACHE_ID, EffectStorageEvent, InternalCacheStorageEvent, LocalResource, type ReactiveStorage, ReactiveStorageOptions, SessionResource, getParamCompanion as _getParamCompanion, initMeta as _initMeta, configureLocalStorage, configureSessionStorage, effect, field, getCacheStorage, getLocalStorage, getSessionStorage, input };
430
+ export { type KeyFn, type ReactiveStorage, type ValueTransition, getParamCompanion as _getParamCompanion, initMeta as _initMeta };
354
431
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","names":[],"sources":["../src/storage/cache.ts","../src/storage/storage.ts","../src/storage/-private/storage-infra.ts","../src/storage/storage-resource.ts"],"mappings":";cAEa;UAKI;EACf;EACA;EACA;EACA;;UAEe;EACf,aAAa;EACb;EACA;EACA;;;;;;;;cAkEW,wBAAwB;;EAInC,OAAO;EACP;EACA,iBAAiB;EAYjB,YAAY;MAMR;EA4BJ;EAKA,QAAQ;EAIR,IAAI;EAgBJ,WAAW;EAQX,QAAQ,aAAa;;;;;SAed,IAAI,mBAAqC,QAAQ;SASjD,YAAY,mBAAqC;;;;;SAYjD;;;;UCtMQ;;;;;EAKf;;;;;EAMA;;;;;EAMA,mBAAmB,aAAa,4BAA4B;;;;;;;iBAgB9C,mBAAmB;iBAOnB,qBAAqB;iBAQrB,gBAAgB,4BAAkC;;;;;iBAelD,sBAAsB,SAAS;;;;;iBAQ/B,wBAAwB,SAAS;KA8BrC,qBAAqB,oBAAoB;;;;;;;cAQ/C,2BAA2B;UACvB;UACA;UACA;UACA;UAEQ;UACA;UAER;EACR,UAAU,aAAa,KAAK,OAAO;EAKnC,YAAY,SAAS,SAAS,UAAS;;;;MA2CnC;;;;EAOJ,SAAS;;;;EAsBT,QAAQ;;;;EAyBR,QAAQ,aAAa;;;;EA2DrB,WAAW;;;;EAsBX;;;;EAeA,IAAI;;;;;;;UC3TW;;;;;EAMf,YAAY,gBAAgB;;;;;EAM5B,cAAc,kBAAkB;;;;;;;;;;EAWhC,cAAc;;UAGN,4BAA4B;EACpC;;UAGe,gBAAgB;EAC/B;EACA,MAAM;EACN,IAAI;;;;;UAMW;EACf;EACA;EACA,MAAM;EACN;EACA,eAAe;EACf,QAAQ,qBAAqB,QAAQ;EACrC,cAAc;EACd,cAAc,YAAY;EAC1B;EACA,WAAW,gBAAgB;;;;;;;;;;;KAajB,SAAS;;;;;;;iBAaL,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;;iBAkT1B,kBAAkB,kBAAkB,kBAAkB;;;;;;;;;;;;;;;;;iBCzWtD,cAAc,aAAa,QAAQ;;;;;;;;;;;;;;;iBAkBnC,gBAAgB,aAAa,QAAQ;;;;;;;;;;;;;;;;;;;;iBAuBrC,cAAc,aAAa,OAAO,4BAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCpE,MAAM,sCAAsC;iBAC5C,MAAM,gBAAgB,aAAa,aAAa;iBAgBhD,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoF7C,OAAO,KAAK,GAAG,QAAQ,gBAAgB,aAAa,6BAA6B"}
1
+ {"version":3,"file":"storage.d.ts","names":[],"sources":["../src/storage/cache.ts","../src/storage/storage.ts","../src/storage/query-params.ts","../src/storage/-private/storage-infra.ts","../src/storage/storage-resource.ts"],"mappings":";qBAEa;iBAKI;EACf;EACA;EACA;EACA;;iBAEe;EACf,aAAa;EACb;EACA;EACA;;;;;;;;qBAkEW,wBAAwB;;EAInC,OAAO;EACP;EACA,iBAAiB;EAYjB,YAAY;MAMR;EA4BJ;EAKA,QAAQ;EAIR,IAAI;EAgBJ,WAAW;EAQX,QAAQ,aAAa;;;;;SAed,IAAI,mBAAqC,QAAQ;SASjD,YAAY,mBAAqC;;;;;SAYjD;;;;iBCtMQ;;;;;EAKf;;;;;EAMA;;;;;EAMA,mBAAmB,aAAa,4BAA4B;;;;;;;wBAgB9C,mBAAmB;wBAOnB,qBAAqB;wBAQrB,gBAAgB,4BAAkC;;;;;wBAelD,sBAAsB,SAAS;;;;;wBAQ/B,wBAAwB,SAAS;YA8BrC,qBAAqB,oBAAoB;;;;;;;;;;;;;;;;;;;wBAoBrC,eAAe,WAAW,OAAO;;;;;;;cAe3C,2BAA2B;UACvB;UACA;UACA;UACA;UAEQ;UACA;UAER;EACR,UAAU,aAAa,KAAK,OAAO;EAKnC,YAAY,SAAS,SAAS,UAAS;;;;MAyCnC;;;;EAOJ,SAAS;;;;EAsBT,QAAQ;;;;EAyBR,QAAQ,aAAa;;;;EA2DrB,WAAW;;;;EAsBX;;;;EAeA,IAAI;;;;;;;iBCpVW;;;;;EAKf,YAAY,gBAAgB;;;;;EAK5B,cAAc,kBAAkB;;;;;;;;;;EAUhC,cAAc;;;;;;;;;;;;;;wBAeA,gBAAgB;;;;;;;;;;;;;;;wBAqBhB,YAAY,oBAAoB,cAAc,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+CrF,MAAM,QAAQ,cAAc;;;UCzGlC,4BAA4B;EACpC;;UAGe,gBAAgB;EAC/B;EACA,MAAM;EACN,IAAI;;;;;UAMW;EACf;EACA;EACA,MAAM;EACN;EACA,eAAe;EACf,QAAQ,qBAAqB,QAAQ;EACrC,cAAc;EACd,cAAc,YAAY;EAC1B;EACA,WAAW,gBAAgB;;;;;;;;;;;KAajB,SAAS;;;;;;;iBAaL,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;;iBAsT1B,kBAAkB,kBAAkB,kBAAkB;;;;;;;;;;;;;;;;;wBCjVtD,cAAc,aAAa,QAAQ;;;;;;;;;;;;;;;wBAkBnC,gBAAgB,aAAa,QAAQ;;;;;;;;;;;;;;;;;;;;wBAuBrC,cAAc,aAAa,OAAO,4BAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAmCpE,MAAM,sCAAsC;wBAC5C,MAAM,gBAAgB,aAAa,aAAa;wBAgBhD,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAoF7C,OAAO,KAAK,GAAG,QAAQ,gBAAgB,aAAa,6BAA6B"}
package/dist/storage.js CHANGED
@@ -8,6 +8,7 @@ import { defineSignal, entangleSignal, getOrCreateInternalSignal, makeInitialize
8
8
  */
9
9
  var SignalMap = class {
10
10
  _map = {};
11
+ _size = 0;
11
12
  _signals = withSignalStore(this._map);
12
13
  subscribe(key) {
13
14
  macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
@@ -15,8 +16,7 @@ var SignalMap = class {
15
16
  })(typeof key === "string");
16
17
  const existing = this._signals.has(key);
17
18
  entangleSignal(this._signals, this._map, key, void 0);
18
- const size = this._size;
19
- this._size = existing ? size : size + 1;
19
+ if (!existing) this._size += 1;
20
20
  return existing;
21
21
  }
22
22
  notify(key) {
@@ -34,7 +34,6 @@ var SignalMap = class {
34
34
  return this._size;
35
35
  }
36
36
  };
37
- defineSignal(SignalMap.prototype, "_size", 0);
38
37
 
39
38
  //#endregion
40
39
  //#region src/storage/cache.ts
@@ -273,6 +272,31 @@ function isStorageUnavailableError(error) {
273
272
  return false;
274
273
  }
275
274
  /**
275
+ * Subscribes to storage-change events, whether they originate from the
276
+ * native Storage API (a `StorageEvent`, fired cross-tab) or from
277
+ * {@link CacheStorage}'s own same-tab notifications (dispatched as a
278
+ * `CustomEvent` under the same 'storage' name — see `emitStorageEvent`
279
+ * in `./cache.ts`).
280
+ *
281
+ * Returns an unsubscribe function.
282
+ *
283
+ * This can't be expressed by widening the global `WindowEventMap.storage`
284
+ * type: that entry is inherited from `WindowEventHandlersEventMap` as
285
+ * `StorageEvent`, and a declaration-merged override has to stay assignable
286
+ * to the type it's overriding, not the other way around — deliberately
287
+ * reusing this event name for a wider union has no way to satisfy that.
288
+ *
289
+ * Route storage-event subscribers through this helper instead of calling
290
+ * `window.addEventListener('storage', ...)` directly.
291
+ */
292
+ function onStorageEvent(listener) {
293
+ const handler = (event) => {
294
+ listener("detail" in event ? event.detail : event);
295
+ };
296
+ window.addEventListener("storage", handler);
297
+ return () => window.removeEventListener("storage", handler);
298
+ }
299
+ /**
276
300
  * A reactive wrapper around the Web Storage API (localStorage/sessionStorage)
277
301
  * that provides signal-based access to storage items and length.
278
302
  *
@@ -304,8 +328,7 @@ var ReactiveStorage = class {
304
328
  this._length = 0;
305
329
  } else throw error;
306
330
  }
307
- if (!this._memoryOnly) window.addEventListener("storage", (event) => {
308
- const data = "detail" in event ? event.detail : event;
331
+ if (!this._memoryOnly) onStorageEvent((data) => {
309
332
  if (data.storageArea === storage) {
310
333
  this._values[data.key] = data.newValue;
311
334
  this._signals.notify(data.key);
@@ -444,9 +467,6 @@ defineSignal(ReactiveStorage.prototype, "_signals", makeInitializer(() => new Si
444
467
  //#endregion
445
468
  //#region src/storage/-private/storage-infra.ts
446
469
  /**
447
- * Configuration options for fields that are also query parameters
448
- */
449
- /**
450
470
  * Metadata attached to persisted resource classes
451
471
  */
452
472
  /**
@@ -526,8 +546,8 @@ function keyFor(meta, key) {
526
546
  return `persisted:${meta.id}:${key}`;
527
547
  }
528
548
  function getStorage(type, namespace) {
529
- if (type === "local-resource") return getLocalStorage();
530
- else if (type === "session-resource") return getSessionStorage();
549
+ if (type === "local-resource" || type === "local-storage") return getLocalStorage();
550
+ else if (type === "session-resource" || type === "session-storage") return getSessionStorage();
531
551
  else return getCacheStorage(namespace);
532
552
  }
533
553
  /**
@@ -910,5 +930,97 @@ function effect(fn, type) {
910
930
  }
911
931
 
912
932
  //#endregion
913
- export { CacheResource, CacheStorage, DEFAULT_CACHE_ID, LocalResource, SessionResource, getParamCompanion as _getParamCompanion, initMeta as _initMeta, configureLocalStorage, configureSessionStorage, effect, field, getCacheStorage, getLocalStorage, getSessionStorage, input };
933
+ //#region src/storage/query-params.ts
934
+ /**
935
+ * Configuration options for fields that are also query parameters
936
+ */
937
+ /**
938
+ * Creates a {@link ParamConfig} for boolean fields that serialize to '1' or null.
939
+ *
940
+ * @returns ParamConfig for boolean fields
941
+ *
942
+ * @example
943
+ * ```ts
944
+ * @param(BooleanParam())
945
+ * @field
946
+ * myFlag: boolean = false;
947
+ * ```
948
+ */
949
+ function BooleanParam() {
950
+ return {
951
+ serialize: (value) => value ? "1" : null,
952
+ deserialize: (urlValue) => urlValue === "1"
953
+ };
954
+ }
955
+ /**
956
+ * Creates a {@link ParamConfig} for numeric fields with default value checking.
957
+ *
958
+ * @param precision - When given, the number of digits to serialize after the decimal point
959
+ * @param getDefault - Function to get the default value for comparison
960
+ * @returns ParamConfig for number fields
961
+ *
962
+ * @example
963
+ * ```ts
964
+ * @param(NumberParam(2, function (instance: MyClass) { return instance.defaultZoom; }))
965
+ * @field
966
+ * zoom: number = 12;
967
+ * ```
968
+ */
969
+ function NumberParam(precision, getDefault) {
970
+ const isPrecise = typeof precision === "number";
971
+ return {
972
+ serialize: function(value) {
973
+ if (typeof value !== "number") return null;
974
+ return isPrecise ? value.toFixed(precision) : value.toString();
975
+ },
976
+ deserialize: (urlValue) => {
977
+ const num = Number(urlValue);
978
+ return isNaN(num) ? null : num;
979
+ },
980
+ getDefault: (instance) => {
981
+ return getDefault?.(instance);
982
+ }
983
+ };
984
+ }
985
+ /**
986
+ * Decorator which marks a field as a query parameter.
987
+ *
988
+ * This decorator only stores metadata - it does not change the property behavior.
989
+ * The field will operate as a normal `@field` until a router integration consumes it.
990
+ *
991
+ * The provided {@link ParamConfig} is used to:
992
+ * - Serialize values for the URL
993
+ * - Deserialize values from the URL
994
+ * - Compare URL and local values
995
+ * - Determine when to include/exclude params from the URL
996
+ *
997
+ * @param config - Configuration for URL serialization/deserialization
998
+ *
999
+ * @example
1000
+ * ```ts
1001
+ * @SessionResource('map-state')
1002
+ * class MapState {
1003
+ * @param({
1004
+ * serialize: (value: unknown) => (value ? '1' : null),
1005
+ * deserialize: (urlValue: string) => urlValue === '1',
1006
+ * })
1007
+ * @field
1008
+ * active: boolean = false;
1009
+ * }
1010
+ * ```
1011
+ */
1012
+ function param(config) {
1013
+ return function(target, key, desc) {
1014
+ macroCondition(getGlobalConfig().WarpDriveMirror.env.DEBUG) && ((test) => {
1015
+ if (!test) throw new Error("param decorator only supports string keys");
1016
+ })(typeof key === "string");
1017
+ const meta = initMeta(target);
1018
+ if (!meta.paramConfigs) meta.paramConfigs = /* @__PURE__ */ new Map();
1019
+ meta.paramConfigs.set(key, config);
1020
+ return desc;
1021
+ };
1022
+ }
1023
+
1024
+ //#endregion
1025
+ export { BooleanParam, CacheResource, CacheStorage, DEFAULT_CACHE_ID, LocalResource, NumberParam, SessionResource, getParamCompanion as _getParamCompanion, initMeta as _initMeta, configureLocalStorage, configureSessionStorage, effect, field, getCacheStorage, getLocalStorage, getSessionStorage, input, onStorageEvent, param };
914
1026
  //# sourceMappingURL=storage.js.map