gjendje 0.4.3 → 0.4.4

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.
@@ -364,21 +364,12 @@ function createBucketAdapter(key, bucketOptions, options) {
364
364
  const listeners = createListeners();
365
365
  let lastNotifiedValue = defaultValue;
366
366
  const notifyListeners = () => listeners.notify(lastNotifiedValue);
367
- let delegate = null;
367
+ const fallbackStorage = fallbackScope === "tab" ? sessionStorage : localStorage;
368
+ let delegate = createStorageAdapter(fallbackStorage, key, options);
368
369
  let isDestroyed = false;
369
- function read() {
370
- if (!delegate) return defaultValue;
371
- return delegate.get();
372
- }
373
- function write(value) {
374
- if (!delegate) return;
375
- delegate.set(value);
376
- }
377
370
  const ready = (async () => {
371
+ if (!isBucketSupported()) return;
378
372
  try {
379
- if (!isBucketSupported()) {
380
- throw new Error("Storage Buckets not supported");
381
- }
382
373
  const openOptions = {
383
374
  persisted: bucketOptions.persisted ?? false,
384
375
  durability: "strict"
@@ -406,20 +397,20 @@ function createBucketAdapter(key, bucketOptions, options) {
406
397
  }
407
398
  }
408
399
  const bucketManager = navigator.storageBuckets;
409
- if (!bucketManager) throw new Error("Storage Buckets not supported");
400
+ if (!bucketManager) return;
410
401
  const bucket = await bucketManager.open(bucketOptions.name, openOptions);
411
402
  const storage = await bucket.localStorage();
403
+ if (isDestroyed) return;
404
+ const currentValue = delegate.get();
405
+ const hadUserWrite = !shallowEqual(currentValue, defaultValue);
406
+ delegate.destroy?.();
412
407
  delegate = createStorageAdapter(storage, key, options);
408
+ if (hadUserWrite) {
409
+ delegate.set(currentValue);
410
+ }
413
411
  } catch {
414
- await Promise.resolve();
415
- const fallbackStorage = fallbackScope === "tab" ? sessionStorage : localStorage;
416
- delegate = createStorageAdapter(fallbackStorage, key, options);
417
- }
418
- if (isDestroyed) {
419
- delegate?.destroy?.();
420
- delegate = null;
421
- return;
422
412
  }
413
+ if (isDestroyed) return;
423
414
  const storedValue = delegate.get();
424
415
  if (!shallowEqual(storedValue, defaultValue)) {
425
416
  lastNotifiedValue = storedValue;
@@ -433,10 +424,10 @@ function createBucketAdapter(key, bucketOptions, options) {
433
424
  return {
434
425
  ready,
435
426
  get() {
436
- return read();
427
+ return delegate.get();
437
428
  },
438
429
  set(value) {
439
- write(value);
430
+ delegate.set(value);
440
431
  lastNotifiedValue = value;
441
432
  notify(notifyListeners);
442
433
  },
@@ -444,8 +435,7 @@ function createBucketAdapter(key, bucketOptions, options) {
444
435
  destroy() {
445
436
  isDestroyed = true;
446
437
  listeners.clear();
447
- delegate?.destroy?.();
448
- delegate = null;
438
+ delegate.destroy?.();
449
439
  }
450
440
  };
451
441
  }
@@ -366,21 +366,12 @@ function createBucketAdapter(key, bucketOptions, options) {
366
366
  const listeners = createListeners();
367
367
  let lastNotifiedValue = defaultValue;
368
368
  const notifyListeners = () => listeners.notify(lastNotifiedValue);
369
- let delegate = null;
369
+ const fallbackStorage = fallbackScope === "tab" ? sessionStorage : localStorage;
370
+ let delegate = createStorageAdapter(fallbackStorage, key, options);
370
371
  let isDestroyed = false;
371
- function read() {
372
- if (!delegate) return defaultValue;
373
- return delegate.get();
374
- }
375
- function write(value) {
376
- if (!delegate) return;
377
- delegate.set(value);
378
- }
379
372
  const ready = (async () => {
373
+ if (!isBucketSupported()) return;
380
374
  try {
381
- if (!isBucketSupported()) {
382
- throw new Error("Storage Buckets not supported");
383
- }
384
375
  const openOptions = {
385
376
  persisted: bucketOptions.persisted ?? false,
386
377
  durability: "strict"
@@ -408,20 +399,20 @@ function createBucketAdapter(key, bucketOptions, options) {
408
399
  }
409
400
  }
410
401
  const bucketManager = navigator.storageBuckets;
411
- if (!bucketManager) throw new Error("Storage Buckets not supported");
402
+ if (!bucketManager) return;
412
403
  const bucket = await bucketManager.open(bucketOptions.name, openOptions);
413
404
  const storage = await bucket.localStorage();
405
+ if (isDestroyed) return;
406
+ const currentValue = delegate.get();
407
+ const hadUserWrite = !shallowEqual(currentValue, defaultValue);
408
+ delegate.destroy?.();
414
409
  delegate = createStorageAdapter(storage, key, options);
410
+ if (hadUserWrite) {
411
+ delegate.set(currentValue);
412
+ }
415
413
  } catch {
416
- await Promise.resolve();
417
- const fallbackStorage = fallbackScope === "tab" ? sessionStorage : localStorage;
418
- delegate = createStorageAdapter(fallbackStorage, key, options);
419
- }
420
- if (isDestroyed) {
421
- delegate?.destroy?.();
422
- delegate = null;
423
- return;
424
414
  }
415
+ if (isDestroyed) return;
425
416
  const storedValue = delegate.get();
426
417
  if (!shallowEqual(storedValue, defaultValue)) {
427
418
  lastNotifiedValue = storedValue;
@@ -435,10 +426,10 @@ function createBucketAdapter(key, bucketOptions, options) {
435
426
  return {
436
427
  ready,
437
428
  get() {
438
- return read();
429
+ return delegate.get();
439
430
  },
440
431
  set(value) {
441
- write(value);
432
+ delegate.set(value);
442
433
  lastNotifiedValue = value;
443
434
  notify(notifyListeners);
444
435
  },
@@ -446,8 +437,7 @@ function createBucketAdapter(key, bucketOptions, options) {
446
437
  destroy() {
447
438
  isDestroyed = true;
448
439
  listeners.clear();
449
- delegate?.destroy?.();
450
- delegate = null;
440
+ delegate.destroy?.();
451
441
  }
452
442
  };
453
443
  }
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunkWYSSCNJG_cjs = require('./chunk-WYSSCNJG.cjs');
3
+ var chunkZQ2PWVTL_cjs = require('./chunk-ZQ2PWVTL.cjs');
4
4
 
5
5
  // src/collection.ts
6
6
  function collection(key, options) {
7
- const base = chunkWYSSCNJG_cjs.createBase(key, options);
7
+ const base = chunkZQ2PWVTL_cjs.createBase(key, options);
8
8
  const watchers = /* @__PURE__ */ new Map();
9
9
  let prevItems = base.get();
10
10
  const unsubscribe = base.subscribe((next) => {
@@ -139,7 +139,7 @@ function collection(key, options) {
139
139
  // src/computed.ts
140
140
  var computedCounter = 0;
141
141
  function computed(deps, fn, options) {
142
- const listeners = chunkWYSSCNJG_cjs.createListeners();
142
+ const listeners = chunkZQ2PWVTL_cjs.createListeners();
143
143
  const instanceKey = options?.key ?? `computed:${computedCounter++}`;
144
144
  let cached;
145
145
  let isDirty = true;
@@ -164,7 +164,7 @@ function computed(deps, fn, options) {
164
164
  };
165
165
  const markDirty = () => {
166
166
  isDirty = true;
167
- chunkWYSSCNJG_cjs.notify(notifyListeners);
167
+ chunkZQ2PWVTL_cjs.notify(notifyListeners);
168
168
  };
169
169
  const unsubscribers = new Array(depLen);
170
170
  for (let i = 0; i < depLen; i++) {
@@ -224,7 +224,7 @@ function computed(deps, fn, options) {
224
224
 
225
225
  // src/devtools.ts
226
226
  function snapshot() {
227
- const registry = chunkWYSSCNJG_cjs.getRegistry();
227
+ const registry = chunkZQ2PWVTL_cjs.getRegistry();
228
228
  const result = [];
229
229
  for (const instance of registry.values()) {
230
230
  result.push({
@@ -410,39 +410,39 @@ function state(key, optionsOrDefault) {
410
410
  if (!key) {
411
411
  throw new Error("[state] key must be a non-empty string.");
412
412
  }
413
- const config = chunkWYSSCNJG_cjs.getConfig();
413
+ const config = chunkZQ2PWVTL_cjs.getConfig();
414
414
  if (config.keyPattern && !config.keyPattern.test(key)) {
415
415
  throw new Error(
416
416
  `[gjendje] Key "${key}" does not match the configured keyPattern ${config.keyPattern}.`
417
417
  );
418
418
  }
419
419
  const scope = options.scope ?? config.scope ?? "render";
420
- const rKey = chunkWYSSCNJG_cjs.scopedKey(key, scope);
421
- const existing = chunkWYSSCNJG_cjs.getRegistered(rKey);
420
+ const rKey = chunkZQ2PWVTL_cjs.scopedKey(key, scope);
421
+ const existing = chunkZQ2PWVTL_cjs.getRegistered(rKey);
422
422
  if (existing && !existing.isDestroyed) {
423
423
  if (config.warnOnDuplicate) {
424
- chunkWYSSCNJG_cjs.log("warn", `Duplicate state("${key}") with scope "${scope}". Returning cached instance.`);
424
+ chunkZQ2PWVTL_cjs.log("warn", `Duplicate state("${key}") with scope "${scope}". Returning cached instance.`);
425
425
  }
426
426
  return existing;
427
427
  }
428
428
  if (scope === "render" && !options.ssr && !config.ssr) {
429
429
  if (options.sync) {
430
- chunkWYSSCNJG_cjs.log(
430
+ chunkZQ2PWVTL_cjs.log(
431
431
  "warn",
432
432
  `sync: true is ignored for scope "render". Only "local" and "bucket" scopes support cross-tab sync.`
433
433
  );
434
434
  }
435
- const instance = chunkWYSSCNJG_cjs.createRenderState(key, rKey, options, config);
436
- chunkWYSSCNJG_cjs.registerByKey(rKey, key, scope, instance, config);
435
+ const instance = chunkZQ2PWVTL_cjs.createRenderState(key, rKey, options, config);
436
+ chunkZQ2PWVTL_cjs.registerByKey(rKey, key, scope, instance, config);
437
437
  return instance;
438
438
  }
439
- return chunkWYSSCNJG_cjs.createBase(key, options);
439
+ return chunkZQ2PWVTL_cjs.createBase(key, options);
440
440
  }
441
441
 
442
442
  // src/previous.ts
443
443
  var previousCounter = 0;
444
444
  function previous(source, options) {
445
- const listeners = chunkWYSSCNJG_cjs.createListeners();
445
+ const listeners = chunkZQ2PWVTL_cjs.createListeners();
446
446
  const instanceKey = options?.key ?? `previous:${previousCounter++}`;
447
447
  let prev;
448
448
  let current = source.get();
@@ -452,7 +452,7 @@ function previous(source, options) {
452
452
  prev = current;
453
453
  current = next;
454
454
  if (old !== prev) {
455
- chunkWYSSCNJG_cjs.notify(() => listeners.notify(prev));
455
+ chunkZQ2PWVTL_cjs.notify(() => listeners.notify(prev));
456
456
  }
457
457
  });
458
458
  let destroyedPromise;
@@ -514,7 +514,7 @@ function readonly(instance) {
514
514
  // src/select.ts
515
515
  var selectCounter = 0;
516
516
  function select(source, fn, options) {
517
- const listeners = chunkWYSSCNJG_cjs.createListeners();
517
+ const listeners = chunkZQ2PWVTL_cjs.createListeners();
518
518
  const instanceKey = options?.key ?? `select:${selectCounter++}`;
519
519
  let cached;
520
520
  let isDirty = true;
@@ -533,7 +533,7 @@ function select(source, fn, options) {
533
533
  };
534
534
  const markDirty = () => {
535
535
  isDirty = true;
536
- chunkWYSSCNJG_cjs.notify(notifyListeners);
536
+ chunkZQ2PWVTL_cjs.notify(notifyListeners);
537
537
  };
538
538
  const unsubscribe = source.subscribe(markDirty);
539
539
  recompute();
@@ -585,15 +585,15 @@ function select(source, fn, options) {
585
585
 
586
586
  Object.defineProperty(exports, "batch", {
587
587
  enumerable: true,
588
- get: function () { return chunkWYSSCNJG_cjs.batch; }
588
+ get: function () { return chunkZQ2PWVTL_cjs.batch; }
589
589
  });
590
590
  Object.defineProperty(exports, "configure", {
591
591
  enumerable: true,
592
- get: function () { return chunkWYSSCNJG_cjs.configure; }
592
+ get: function () { return chunkZQ2PWVTL_cjs.configure; }
593
593
  });
594
594
  Object.defineProperty(exports, "shallowEqual", {
595
595
  enumerable: true,
596
- get: function () { return chunkWYSSCNJG_cjs.shallowEqual; }
596
+ get: function () { return chunkZQ2PWVTL_cjs.shallowEqual; }
597
597
  });
598
598
  exports.collection = collection;
599
599
  exports.computed = computed;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createBase, createListeners, getRegistry, getConfig, scopedKey, getRegistered, log, createRenderState, registerByKey, notify } from './chunk-OHNTBP7O.js';
2
- export { batch, configure, shallowEqual } from './chunk-OHNTBP7O.js';
1
+ import { createBase, createListeners, getRegistry, getConfig, scopedKey, getRegistered, log, createRenderState, registerByKey, notify } from './chunk-WLY6NN5P.js';
2
+ export { batch, configure, shallowEqual } from './chunk-WLY6NN5P.js';
3
3
 
4
4
  // src/collection.ts
5
5
  function collection(key, options) {
package/dist/server.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkWYSSCNJG_cjs = require('./chunk-WYSSCNJG.cjs');
3
+ var chunkZQ2PWVTL_cjs = require('./chunk-ZQ2PWVTL.cjs');
4
4
  var async_hooks = require('async_hooks');
5
5
 
6
6
  var als = new async_hooks.AsyncLocalStorage();
@@ -9,7 +9,7 @@ async function withServerSession(fn) {
9
9
  return als.run(store, fn);
10
10
  }
11
11
  function createServerAdapter(key, defaultValue) {
12
- const listeners = chunkWYSSCNJG_cjs.createListeners();
12
+ const listeners = chunkZQ2PWVTL_cjs.createListeners();
13
13
  function getStore() {
14
14
  return als.getStore();
15
15
  }
@@ -31,7 +31,7 @@ function createServerAdapter(key, defaultValue) {
31
31
  }
32
32
  store.set(key, value);
33
33
  lastNotifiedValue = value;
34
- chunkWYSSCNJG_cjs.notify(notifyListeners);
34
+ chunkZQ2PWVTL_cjs.notify(notifyListeners);
35
35
  },
36
36
  subscribe: listeners.subscribe,
37
37
  destroy() {
@@ -39,7 +39,7 @@ function createServerAdapter(key, defaultValue) {
39
39
  }
40
40
  };
41
41
  }
42
- chunkWYSSCNJG_cjs.registerServerAdapter(createServerAdapter);
42
+ chunkZQ2PWVTL_cjs.registerServerAdapter(createServerAdapter);
43
43
 
44
44
  exports.createServerAdapter = createServerAdapter;
45
45
  exports.withServerSession = withServerSession;
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { registerServerAdapter, createListeners, notify } from './chunk-OHNTBP7O.js';
1
+ import { registerServerAdapter, createListeners, notify } from './chunk-WLY6NN5P.js';
2
2
  import { AsyncLocalStorage } from 'async_hooks';
3
3
 
4
4
  var als = new AsyncLocalStorage();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gjendje",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "TypeScript state management",
5
5
  "keywords": [
6
6
  "state",