signalium 2.2.1 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/development/{core-api-BLfPllpC.js → core-api-C6HCIyL3.js} +2 -2
  3. package/dist/cjs/development/{core-api-BLfPllpC.js.map → core-api-C6HCIyL3.js.map} +1 -1
  4. package/dist/cjs/development/{debug-C4VkJKKv.js → debug-3nd-6Gnf.js} +82 -51
  5. package/dist/cjs/development/debug-3nd-6Gnf.js.map +1 -0
  6. package/dist/cjs/development/debug.js +1 -1
  7. package/dist/cjs/development/index.js +2 -2
  8. package/dist/cjs/development/react/index.js +2 -2
  9. package/dist/cjs/development/utils.js +2 -2
  10. package/dist/cjs/production/{contexts-D9PmMMc5.js → contexts-DoZWv_3I.js} +82 -51
  11. package/dist/cjs/production/contexts-DoZWv_3I.js.map +1 -0
  12. package/dist/cjs/production/{core-api-nNbd4L7C.js → core-api-CUviCxtM.js} +2 -2
  13. package/dist/cjs/production/{core-api-nNbd4L7C.js.map → core-api-CUviCxtM.js.map} +1 -1
  14. package/dist/cjs/production/debug.js +1 -1
  15. package/dist/cjs/production/index.js +2 -2
  16. package/dist/cjs/production/react/index.js +2 -2
  17. package/dist/cjs/production/utils.js +2 -2
  18. package/dist/esm/development/{core-api-BKTJuFkJ.js → core-api-CjsScNn1.js} +2 -2
  19. package/dist/esm/development/{core-api-BKTJuFkJ.js.map → core-api-CjsScNn1.js.map} +1 -1
  20. package/dist/esm/development/{debug-qm_Izoi_.js → debug-BfudYKc4.js} +82 -51
  21. package/dist/esm/development/debug-BfudYKc4.js.map +1 -0
  22. package/dist/esm/development/debug.js +1 -1
  23. package/dist/esm/development/index.js +2 -2
  24. package/dist/esm/development/react/index.js +2 -2
  25. package/dist/esm/development/utils.js +3 -3
  26. package/dist/esm/internals/async.d.ts.map +1 -1
  27. package/dist/esm/internals/reactive.d.ts +14 -4
  28. package/dist/esm/internals/reactive.d.ts.map +1 -1
  29. package/dist/esm/internals/scheduling.d.ts.map +1 -1
  30. package/dist/esm/internals/utils/hash.d.ts +1 -3
  31. package/dist/esm/internals/utils/hash.d.ts.map +1 -1
  32. package/dist/esm/internals/watch.d.ts.map +1 -1
  33. package/dist/esm/production/{contexts-BLI-Vgt4.js → contexts-CilfS6eG.js} +82 -51
  34. package/dist/esm/production/contexts-CilfS6eG.js.map +1 -0
  35. package/dist/esm/production/{core-api-Ckj2uqeX.js → core-api-tTQttL8R.js} +2 -2
  36. package/dist/esm/production/{core-api-Ckj2uqeX.js.map → core-api-tTQttL8R.js.map} +1 -1
  37. package/dist/esm/production/debug.js +1 -1
  38. package/dist/esm/production/index.js +2 -2
  39. package/dist/esm/production/react/index.js +2 -2
  40. package/dist/esm/production/utils.js +3 -3
  41. package/dist/esm/types.d.ts +5 -1
  42. package/dist/esm/types.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/cjs/development/debug-C4VkJKKv.js.map +0 -1
  45. package/dist/cjs/production/contexts-D9PmMMc5.js.map +0 -1
  46. package/dist/esm/development/debug-qm_Izoi_.js.map +0 -1
  47. package/dist/esm/production/contexts-BLI-Vgt4.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # signalium
2
2
 
3
+ ## 2.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 6c19cdc: Add `skipInitial` option to `watcher.addListener()` to skip the notification fired on initial activation
8
+
9
+ Fix: Reset `listeners.updatedAt` when all listeners are removed, so re-subscribing correctly fires the initial notification. Previously, stale `updatedAt` state could cause missed notifications after unsubscribing and re-subscribing.
10
+
11
+ ## 2.2.2
12
+
13
+ ### Patch Changes
14
+
15
+ - 0aedc29: Fix bugs with async reactive functions never resolving
16
+ - 5f0aafc: Add better tests for the hash function, fix some minor edge cases
17
+
3
18
  ## 2.2.1
4
19
 
5
20
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const debug = require("./debug-C4VkJKKv.js");
2
+ const debug = require("./debug-3nd-6Gnf.js");
3
3
  const DERIVED_DEFINITION_MAP = /* @__PURE__ */ new Map();
4
4
  function getReactiveFnAndDefinition(fn, opts) {
5
5
  let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);
@@ -52,4 +52,4 @@ exports.reactiveSignal = reactiveSignal;
52
52
  exports.relay = relay;
53
53
  exports.task = task;
54
54
  exports.watcher = watcher;
55
- //# sourceMappingURL=core-api-BLfPllpC.js.map
55
+ //# sourceMappingURL=core-api-C6HCIyL3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"core-api-BLfPllpC.js","sources":["../../../src/internals/core-api.ts"],"sourcesContent":["import {\n ReactiveTask,\n ReactiveValue,\n Watcher,\n ReactiveOptions,\n RelayActivate,\n type DiscriminatedReactivePromise,\n SignalOptions,\n ReactiveFn,\n ReadonlySignal,\n} from '../types.js';\nimport { getCurrentScope, getScopeOwner, SignalScope } from './contexts.js';\nimport {\n createReactiveDefinition,\n createReactiveSignal,\n ReactiveDefinition as ReactiveDefinition,\n} from './reactive.js';\nimport { createRelay, createTask } from './async.js';\nimport { Tracer } from './trace.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const DERIVED_DEFINITION_MAP = new Map<Function, [(...args: any) => any, ReactiveDefinition<any, any>]>();\n\nexport function getReactiveFnAndDefinition<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): [(...args: Args) => ReactiveValue<T>, ReactiveDefinition<T, Args>] {\n let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);\n\n if (!fnAndDef) {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const defScope = getCurrentScope();\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n const scope = getCurrentScope(defScope);\n const signal = scope.get(def, args as any);\n\n return signal.value;\n };\n\n fnAndDef = [reactiveFn, def];\n\n DERIVED_DEFINITION_MAP.set(fn, fnAndDef);\n }\n\n return fnAndDef;\n}\n\nexport function reactive<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> {\n return getReactiveFnAndDefinition(fn, opts)[0];\n}\n\nexport const reactiveMethod = <T, Args extends unknown[]>(\n owner: object,\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n return getScopeOwner(owner).get(def, args as any).value;\n };\n\n DERIVED_DEFINITION_MAP.set(reactiveFn, [reactiveFn, def]);\n\n return reactiveFn;\n};\n\nexport function relay<T>(activate: RelayActivate<T>, opts?: SignalOptions<T>): DiscriminatedReactivePromise<T> {\n const scope = getCurrentScope();\n\n return createRelay(activate, scope, opts) as DiscriminatedReactivePromise<T>;\n}\n\nexport const task = <T, Args extends unknown[]>(\n fn: (...args: Args) => Promise<T>,\n opts?: SignalOptions<T>,\n): ReactiveTask<T, Args> => {\n const scope = getCurrentScope();\n\n return createTask(fn, scope, opts);\n};\n\nexport function watcher<T>(fn: () => T, opts?: SignalOptions<T> & { isolate?: boolean; tracer?: Tracer }): Watcher<T> {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, undefined, opts?.tracer);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n}\n\n/**\n * Creates a reactive signal from a compute function. This is useful for when you\n * want to create a signal that does not receive parameters, but is still reactive.\n *\n * @param compute\n * @param opts\n * @returns\n */\nexport const reactiveSignal = <T>(\n compute: () => T,\n opts?: SignalOptions<T> & { isolate?: boolean },\n): ReadonlySignal<T> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, compute, opts?.equals, false, undefined, undefined);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n};\n"],"names":["createReactiveDefinition","getCurrentScope","getScopeOwner","createRelay","createTask","SignalScope","createReactiveSignal"],"mappings":";;AAqBO,MAAM,6CAA6B,IAAA;AAEnC,SAAS,2BACd,IACA,MACoE;AACpE,MAAI,WAAW,uBAAuB,IAAI,EAAE;AAE5C,MAAI,CAAC,UAAU;AACb,UAAM,MAAMA,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,UAAM,WAAWC,MAAAA,gBAAA;AAEjB,UAAM,aAAkC,IAAI,SAAS;AACnD,YAAM,QAAQA,MAAAA,gBAAgB,QAAQ;AACtC,YAAM,SAAS,MAAM,IAAI,KAAK,IAAW;AAEzC,aAAO,OAAO;AAAA,IAChB;AAEA,eAAW,CAAC,YAAY,GAAG;AAE3B,2BAAuB,IAAI,IAAI,QAAQ;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,SACd,IACA,MACqB;AACrB,SAAO,2BAA2B,IAAI,IAAI,EAAE,CAAC;AAC/C;AAEO,MAAM,iBAAiB,CAC5B,OACA,IACA,SACwB;AACxB,QAAM,MAAMD,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,QAAM,aAAkC,IAAI,SAAS;AACnD,WAAOE,MAAAA,cAAc,KAAK,EAAE,IAAI,KAAK,IAAW,EAAE;AAAA,EACpD;AAEA,yBAAuB,IAAI,YAAY,CAAC,YAAY,GAAG,CAAC;AAExD,SAAO;AACT;AAEO,SAAS,MAAS,UAA4B,MAA0D;AAC7G,QAAM,QAAQD,MAAAA,gBAAA;AAEd,SAAOE,kBAAY,UAAU,OAAO,IAAI;AAC1C;AAEO,MAAM,OAAO,CAClB,IACA,SAC0B;AAC1B,QAAM,QAAQF,MAAAA,gBAAA;AAEd,SAAOG,iBAAW,IAAI,OAAO,IAAI;AACnC;AAEO,SAAS,QAAW,IAAa,MAA8E;AACpH,QAAM,MAAMJ,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,QAAW,MAAM,MAAM;AAE3G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;AAUO,MAAM,iBAAiB,CAC5B,SACA,SACsB;AACtB,QAAM,MAAMN,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAW,MAAS;AAE7G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;;;;;;;;"}
1
+ {"version":3,"file":"core-api-C6HCIyL3.js","sources":["../../../src/internals/core-api.ts"],"sourcesContent":["import {\n ReactiveTask,\n ReactiveValue,\n Watcher,\n ReactiveOptions,\n RelayActivate,\n type DiscriminatedReactivePromise,\n SignalOptions,\n ReactiveFn,\n ReadonlySignal,\n} from '../types.js';\nimport { getCurrentScope, getScopeOwner, SignalScope } from './contexts.js';\nimport {\n createReactiveDefinition,\n createReactiveSignal,\n ReactiveDefinition as ReactiveDefinition,\n} from './reactive.js';\nimport { createRelay, createTask } from './async.js';\nimport { Tracer } from './trace.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const DERIVED_DEFINITION_MAP = new Map<Function, [(...args: any) => any, ReactiveDefinition<any, any>]>();\n\nexport function getReactiveFnAndDefinition<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): [(...args: Args) => ReactiveValue<T>, ReactiveDefinition<T, Args>] {\n let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);\n\n if (!fnAndDef) {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const defScope = getCurrentScope();\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n const scope = getCurrentScope(defScope);\n const signal = scope.get(def, args as any);\n\n return signal.value;\n };\n\n fnAndDef = [reactiveFn, def];\n\n DERIVED_DEFINITION_MAP.set(fn, fnAndDef);\n }\n\n return fnAndDef;\n}\n\nexport function reactive<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> {\n return getReactiveFnAndDefinition(fn, opts)[0];\n}\n\nexport const reactiveMethod = <T, Args extends unknown[]>(\n owner: object,\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n return getScopeOwner(owner).get(def, args as any).value;\n };\n\n DERIVED_DEFINITION_MAP.set(reactiveFn, [reactiveFn, def]);\n\n return reactiveFn;\n};\n\nexport function relay<T>(activate: RelayActivate<T>, opts?: SignalOptions<T>): DiscriminatedReactivePromise<T> {\n const scope = getCurrentScope();\n\n return createRelay(activate, scope, opts) as DiscriminatedReactivePromise<T>;\n}\n\nexport const task = <T, Args extends unknown[]>(\n fn: (...args: Args) => Promise<T>,\n opts?: SignalOptions<T>,\n): ReactiveTask<T, Args> => {\n const scope = getCurrentScope();\n\n return createTask(fn, scope, opts);\n};\n\nexport function watcher<T>(fn: () => T, opts?: SignalOptions<T> & { isolate?: boolean; tracer?: Tracer }): Watcher<T> {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, undefined, opts?.tracer);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n}\n\n/**\n * Creates a reactive signal from a compute function. This is useful for when you\n * want to create a signal that does not receive parameters, but is still reactive.\n *\n * @param compute\n * @param opts\n * @returns\n */\nexport const reactiveSignal = <T>(\n compute: () => T,\n opts?: SignalOptions<T> & { isolate?: boolean },\n): ReadonlySignal<T> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, compute, opts?.equals, false, undefined, undefined);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n};\n"],"names":["createReactiveDefinition","getCurrentScope","getScopeOwner","createRelay","createTask","SignalScope","createReactiveSignal"],"mappings":";;AAqBO,MAAM,6CAA6B,IAAA;AAEnC,SAAS,2BACd,IACA,MACoE;AACpE,MAAI,WAAW,uBAAuB,IAAI,EAAE;AAE5C,MAAI,CAAC,UAAU;AACb,UAAM,MAAMA,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,UAAM,WAAWC,MAAAA,gBAAA;AAEjB,UAAM,aAAkC,IAAI,SAAS;AACnD,YAAM,QAAQA,MAAAA,gBAAgB,QAAQ;AACtC,YAAM,SAAS,MAAM,IAAI,KAAK,IAAW;AAEzC,aAAO,OAAO;AAAA,IAChB;AAEA,eAAW,CAAC,YAAY,GAAG;AAE3B,2BAAuB,IAAI,IAAI,QAAQ;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,SACd,IACA,MACqB;AACrB,SAAO,2BAA2B,IAAI,IAAI,EAAE,CAAC;AAC/C;AAEO,MAAM,iBAAiB,CAC5B,OACA,IACA,SACwB;AACxB,QAAM,MAAMD,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,QAAM,aAAkC,IAAI,SAAS;AACnD,WAAOE,MAAAA,cAAc,KAAK,EAAE,IAAI,KAAK,IAAW,EAAE;AAAA,EACpD;AAEA,yBAAuB,IAAI,YAAY,CAAC,YAAY,GAAG,CAAC;AAExD,SAAO;AACT;AAEO,SAAS,MAAS,UAA4B,MAA0D;AAC7G,QAAM,QAAQD,MAAAA,gBAAA;AAEd,SAAOE,kBAAY,UAAU,OAAO,IAAI;AAC1C;AAEO,MAAM,OAAO,CAClB,IACA,SAC0B;AAC1B,QAAM,QAAQF,MAAAA,gBAAA;AAEd,SAAOG,iBAAW,IAAI,OAAO,IAAI;AACnC;AAEO,SAAS,QAAW,IAAa,MAA8E;AACpH,QAAM,MAAMJ,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,QAAW,MAAM,MAAM;AAE3G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;AAUO,MAAM,iBAAiB,CAC5B,SACA,SACsB;AACtB,QAAM,MAAMN,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAW,MAAS;AAE7G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;;;;;;;;"}
@@ -432,6 +432,7 @@ function watchActiveSignal(signal2) {
432
432
  const { watchCount } = signal2;
433
433
  const newWatchCount = watchCount + 1;
434
434
  signal2.watchCount = newWatchCount;
435
+ cancelDeactivate(signal2);
435
436
  if (signal2._isActive) {
436
437
  return;
437
438
  }
@@ -454,7 +455,6 @@ function watchSuspendedSignal(signal2) {
454
455
  const newSuspendCount = suspendCount + 1;
455
456
  signal2.watchCount = newWatchCount;
456
457
  signal2.suspendCount = newSuspendCount;
457
- signal2.scope?.removeFromGc(signal2);
458
458
  cancelDeactivate(signal2);
459
459
  if (watchCount === 0) {
460
460
  for (const dep of signal2.deps.keys()) {
@@ -476,6 +476,7 @@ function resumeSignal(signal2) {
476
476
  const { watchCount, suspendCount } = signal2;
477
477
  const newSuspendCount = Math.max(suspendCount - 1, 0);
478
478
  signal2.suspendCount = newSuspendCount;
479
+ cancelDeactivate(signal2);
479
480
  if (watchCount > 0 && !signal2._isActive) {
480
481
  for (const dep of signal2.deps.keys()) {
481
482
  resumeSignal(dep);
@@ -557,6 +558,7 @@ const scheduleDeactivate = (signal2) => {
557
558
  scheduleFlush();
558
559
  };
559
560
  const cancelDeactivate = (signal2) => {
561
+ signal2.scope?.removeFromGc(signal2);
560
562
  PENDING_DEACTIVE.delete(signal2);
561
563
  };
562
564
  const scheduleListeners = (signal2) => {
@@ -1141,10 +1143,10 @@ class ReactivePromiseImpl {
1141
1143
  this._promise = promise;
1142
1144
  const flags = this._flags;
1143
1145
  let awaitSubs = this._awaitSubs;
1144
- if ((flags & 1) === 0) {
1145
- awaitSubs = this._setPending();
1146
- }
1147
1146
  try {
1147
+ if ((flags & 1) === 0) {
1148
+ awaitSubs = this._setPending();
1149
+ }
1148
1150
  const nextValue = await promise;
1149
1151
  if (promise !== this._promise) {
1150
1152
  return;
@@ -1387,6 +1389,9 @@ function createRelay(activate, scope, opts) {
1387
1389
  currentSub = void 0;
1388
1390
  };
1389
1391
  const state = {
1392
+ get isPending() {
1393
+ return (p["_flags"] & 1) !== 0;
1394
+ },
1390
1395
  get value() {
1391
1396
  return p["_value"];
1392
1397
  },
@@ -1436,7 +1441,11 @@ function createTask(task, scope, opts) {
1436
1441
  64
1437
1442
  /* isRunnable */
1438
1443
  );
1444
+ const throwIfRunning = opts?.throwIfRunning === true;
1439
1445
  p["run"] = ((...args) => {
1446
+ if (throwIfRunning && (p["_flags"] & 1) !== 0) {
1447
+ throw new Error("Task is already running");
1448
+ }
1440
1449
  p._setPromise(fn(...args));
1441
1450
  return p;
1442
1451
  });
@@ -1611,30 +1620,22 @@ function hashStr(key, seed = 0) {
1611
1620
  const c1 = 3432918353;
1612
1621
  const c2 = 461845907;
1613
1622
  let i = 0;
1614
- while (i + 4 <= key.length) {
1615
- let k2 = key.charCodeAt(i) & 255 | (key.charCodeAt(i + 1) & 255) << 8 | (key.charCodeAt(i + 2) & 255) << 16 | (key.charCodeAt(i + 3) & 255) << 24;
1616
- k2 = imul(k2, c1);
1617
- k2 = k2 << 15 | k2 >>> 17;
1618
- k2 = imul(k2, c2);
1619
- h ^= k2;
1623
+ while (i + 2 <= key.length) {
1624
+ let k = key.charCodeAt(i) & 65535 | (key.charCodeAt(i + 1) & 65535) << 16;
1625
+ k = imul(k, c1);
1626
+ k = k << 15 | k >>> 17;
1627
+ k = imul(k, c2);
1628
+ h ^= k;
1620
1629
  h = h << 13 | h >>> 19;
1621
1630
  h = imul(h, 5) + 3864292196;
1622
- i += 4;
1623
- }
1624
- let k = 0;
1625
- switch (key.length & 3) {
1626
- case 3:
1627
- k ^= (key.charCodeAt(i + 2) & 255) << 16;
1628
- // eslint-disable-next-line no-fallthrough
1629
- case 2:
1630
- k ^= (key.charCodeAt(i + 1) & 255) << 8;
1631
- // eslint-disable-next-line no-fallthrough
1632
- case 1:
1633
- k ^= key.charCodeAt(i) & 255;
1634
- k = imul(k, c1);
1635
- k = k << 15 | k >>> 17;
1636
- k = imul(k, c2);
1637
- h ^= k;
1631
+ i += 2;
1632
+ }
1633
+ if (key.length & 1) {
1634
+ let k = key.charCodeAt(i) & 65535;
1635
+ k = imul(k, c1);
1636
+ k = k << 15 | k >>> 17;
1637
+ k = imul(k, c2);
1638
+ h ^= k;
1638
1639
  }
1639
1640
  h ^= key.length;
1640
1641
  h ^= h >>> 16;
@@ -1645,8 +1646,9 @@ function hashStr(key, seed = 0) {
1645
1646
  return h >>> 0;
1646
1647
  }
1647
1648
  function hashNumber(num, seed = 0) {
1649
+ let h = num < 0 ? seed ^ 2147483648 : seed;
1648
1650
  num = abs(num);
1649
- let h = seed;
1651
+ const origNum = num;
1650
1652
  const c1 = 3432918353;
1651
1653
  const c2 = 461845907;
1652
1654
  while (num >= 4294967295) {
@@ -1666,7 +1668,7 @@ function hashNumber(num, seed = 0) {
1666
1668
  k = imul(k, c2);
1667
1669
  h ^= k;
1668
1670
  }
1669
- const numBytes = num === 0 ? 1 : floor(log(num) / log(256)) + 1;
1671
+ const numBytes = origNum === 0 ? 1 : floor(log(origNum) / log(256)) + 1;
1670
1672
  h ^= numBytes;
1671
1673
  h ^= h >>> 16;
1672
1674
  h = imul(h, 2246822507);
@@ -1675,12 +1677,12 @@ function hashNumber(num, seed = 0) {
1675
1677
  h ^= h >>> 16;
1676
1678
  return h >>> 0;
1677
1679
  }
1678
- function hashArray(arr) {
1679
- let h = 7;
1680
+ function hashArray(arr, seen) {
1681
+ let h = ARRAY;
1680
1682
  const c1 = 3432918353;
1681
1683
  const c2 = 461845907;
1682
1684
  for (const item of arr) {
1683
- let k = hashValue(item);
1685
+ let k = hashValue(item, seen);
1684
1686
  k = imul(k, c1);
1685
1687
  k = k << 15 | k >>> 17;
1686
1688
  k = imul(k, c2);
@@ -1696,36 +1698,36 @@ function hashArray(arr) {
1696
1698
  h ^= h >>> 16;
1697
1699
  return h >>> 0;
1698
1700
  }
1699
- function hashObject(obj) {
1701
+ function hashObject(obj, seen) {
1700
1702
  let sum = OBJECT;
1701
1703
  const keys = Object.keys(obj);
1702
1704
  for (const key of keys) {
1703
- sum += hashValue(key) ^ hashValue(obj[key]);
1705
+ sum += imul(hashValue(key, seen), 2654435769) ^ hashValue(obj[key], seen);
1704
1706
  }
1705
1707
  return sum >>> 0;
1706
1708
  }
1707
- function hashSet(set) {
1708
- let sum = 13;
1709
+ function hashSet(set, seen) {
1710
+ let sum = SET;
1709
1711
  for (const value of set) {
1710
- sum += hashValue(value);
1712
+ sum += hashValue(value, seen);
1711
1713
  }
1712
1714
  return sum >>> 0;
1713
1715
  }
1714
- function hashMap(map) {
1715
- let sum = 12;
1716
+ function hashMap(map, seen) {
1717
+ let sum = MAP;
1716
1718
  for (const [key, value] of map) {
1717
- sum += hashValue(key) ^ hashValue(value);
1719
+ sum += imul(hashValue(key, seen), 2654435769) ^ hashValue(value, seen);
1718
1720
  }
1719
1721
  return sum >>> 0;
1720
1722
  }
1721
- function hashDate(date) {
1723
+ function hashDate(date, _seen) {
1722
1724
  return hashNumber(
1723
1725
  date.getTime(),
1724
1726
  14
1725
1727
  /* DATE */
1726
1728
  );
1727
1729
  }
1728
- function hashRegExp(regexp) {
1730
+ function hashRegExp(regexp, _seen) {
1729
1731
  const h = hashStr(
1730
1732
  regexp.source + regexp.flags,
1731
1733
  15
@@ -1753,7 +1755,7 @@ const FALSE = hashStr(
1753
1755
  3
1754
1756
  /* FALSE */
1755
1757
  );
1756
- hashStr(
1758
+ const ARRAY = hashStr(
1757
1759
  "array",
1758
1760
  7
1759
1761
  /* ARRAY */
@@ -1763,6 +1765,16 @@ const OBJECT = hashStr(
1763
1765
  8
1764
1766
  /* OBJECT */
1765
1767
  );
1768
+ const SET = hashStr(
1769
+ "set",
1770
+ 13
1771
+ /* SET */
1772
+ );
1773
+ const MAP = hashStr(
1774
+ "map",
1775
+ 12
1776
+ /* MAP */
1777
+ );
1766
1778
  const getObjectProto = Object.getPrototypeOf;
1767
1779
  const PROTO_TO_HASH = /* @__PURE__ */ new Map([
1768
1780
  [Object.prototype, hashObject],
@@ -1773,7 +1785,7 @@ const PROTO_TO_HASH = /* @__PURE__ */ new Map([
1773
1785
  [RegExp.prototype, hashRegExp]
1774
1786
  ]);
1775
1787
  const registerCustomHash = (ctor, hashFn) => {
1776
- PROTO_TO_HASH.set(ctor.prototype, hashFn);
1788
+ PROTO_TO_HASH.set(ctor.prototype, (obj, _seen) => hashFn(obj));
1777
1789
  };
1778
1790
  function hashValue(node, seen = []) {
1779
1791
  switch (typeof node) {
@@ -1814,7 +1826,7 @@ function hashValue(node, seen = []) {
1814
1826
  const hashFn = PROTO_TO_HASH.get(getObjectProto(node));
1815
1827
  if (hashFn) {
1816
1828
  seen.push(node);
1817
- const hash = hashFn(node);
1829
+ const hash = hashFn(node, seen);
1818
1830
  seen.pop();
1819
1831
  return hash;
1820
1832
  }
@@ -1844,9 +1856,16 @@ function getObjectHash(obj) {
1844
1856
  }
1845
1857
  return id;
1846
1858
  }
1847
- const EMPTY_ARRAY_HASH = hashArray([]);
1859
+ const EMPTY_ARRAY_HASH = hashArray([], []);
1848
1860
  function hashReactiveFn(fn, args) {
1849
- return getObjectHash(fn) ^ (args.length > 0 ? hashArray(args) : EMPTY_ARRAY_HASH);
1861
+ const argsHash = args.length > 0 ? hashArray(args, []) : EMPTY_ARRAY_HASH;
1862
+ let k = imul(argsHash, 3432918353);
1863
+ k = k << 15 | k >>> 17;
1864
+ k = imul(k, 461845907);
1865
+ let h = getObjectHash(fn);
1866
+ h ^= k;
1867
+ h = h << 13 | h >>> 19;
1868
+ return imul(h, 5) + 3864292196 >>> 0;
1850
1869
  }
1851
1870
  const objectToIdMap = /* @__PURE__ */ new WeakMap();
1852
1871
  let nextId = 1;
@@ -1993,22 +2012,33 @@ class ReactiveSignal {
1993
2012
  get listeners() {
1994
2013
  return this._listeners ?? (this._listeners = {
1995
2014
  updatedAt: 0,
1996
- current: /* @__PURE__ */ new Set(),
2015
+ current: /* @__PURE__ */ new Map(),
1997
2016
  cachedBoundAdd: this.addListener.bind(this)
1998
2017
  });
1999
2018
  }
2000
2019
  get value() {
2001
2020
  return getSignal(this);
2002
2021
  }
2003
- addListener(listener) {
2022
+ addListener(listener, opts) {
2004
2023
  const { current } = this.listeners;
2005
2024
  if (!current.has(listener)) {
2025
+ let effective = listener;
2026
+ if (opts?.skipInitial) {
2027
+ let initial = true;
2028
+ effective = () => {
2029
+ if (initial) {
2030
+ initial = false;
2031
+ return;
2032
+ }
2033
+ listener();
2034
+ };
2035
+ }
2006
2036
  if (!this._isListener) {
2007
2037
  watchSignal(this, this._isSuspended);
2008
2038
  this.flags |= 16;
2009
2039
  }
2010
2040
  schedulePull(this);
2011
- current.add(listener);
2041
+ current.set(listener, effective);
2012
2042
  }
2013
2043
  return () => {
2014
2044
  if (current.has(listener)) {
@@ -2017,6 +2047,7 @@ class ReactiveSignal {
2017
2047
  cancelPull(this);
2018
2048
  unwatchSignal(this, this._isSuspended);
2019
2049
  this.flags &= -17;
2050
+ this.listeners.updatedAt = 0;
2020
2051
  }
2021
2052
  }
2022
2053
  };
@@ -2064,7 +2095,7 @@ const runListeners = (signal2) => {
2064
2095
  return;
2065
2096
  }
2066
2097
  const { current } = listeners;
2067
- for (const listener of current) {
2098
+ for (const listener of current.values()) {
2068
2099
  listener();
2069
2100
  }
2070
2101
  };
@@ -2259,4 +2290,4 @@ exports.signal = signal;
2259
2290
  exports.unwatchSignal = unwatchSignal;
2260
2291
  exports.watchSignal = watchSignal;
2261
2292
  exports.withContexts = withContexts;
2262
- //# sourceMappingURL=debug-C4VkJKKv.js.map
2293
+ //# sourceMappingURL=debug-3nd-6Gnf.js.map