@fluixi/reactive 1.0.0-alpha.92 → 1.0.0-alpha.94

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 (92) hide show
  1. package/dist/cdn/reactive.cjs +105 -35
  2. package/dist/cdn/reactive.global.js +2 -2
  3. package/dist/cdn/reactive.mjs +105 -35
  4. package/dist/cdn/signal.cjs +1 -1
  5. package/dist/cdn/signal.global.js +2 -2
  6. package/dist/cdn/signal.mjs +1 -1
  7. package/dist/index.cjs +105 -35
  8. package/dist/index.mjs +105 -35
  9. package/dist/lib/index.cjs +106 -36
  10. package/dist/lib/index.mjs +106 -36
  11. package/dist/lib/observable/index.cjs +1 -1
  12. package/dist/lib/observable/index.mjs +1 -1
  13. package/dist/lib/signal/api.cjs +11 -10
  14. package/dist/lib/signal/api.d.ts +5 -1
  15. package/dist/lib/signal/api.d.ts.map +1 -1
  16. package/dist/lib/signal/api.js +4 -2
  17. package/dist/lib/signal/api.mjs +11 -10
  18. package/dist/lib/signal/cached-resource.cjs +77 -34
  19. package/dist/lib/signal/cached-resource.d.ts +48 -68
  20. package/dist/lib/signal/cached-resource.d.ts.map +1 -1
  21. package/dist/lib/signal/cached-resource.js +59 -72
  22. package/dist/lib/signal/cached-resource.mjs +77 -34
  23. package/dist/lib/signal/graph/children.cjs +3 -2
  24. package/dist/lib/signal/graph/children.mjs +3 -2
  25. package/dist/lib/signal/graph/compat.cjs +10 -9
  26. package/dist/lib/signal/graph/compat.d.ts +3 -1
  27. package/dist/lib/signal/graph/compat.d.ts.map +1 -1
  28. package/dist/lib/signal/graph/compat.js +2 -2
  29. package/dist/lib/signal/graph/compat.mjs +10 -9
  30. package/dist/lib/signal/graph/core.cjs +2 -2
  31. package/dist/lib/signal/graph/core.mjs +2 -2
  32. package/dist/lib/signal/graph/debounced.cjs +9 -8
  33. package/dist/lib/signal/graph/debounced.mjs +9 -8
  34. package/dist/lib/signal/graph/derived.cjs +9 -8
  35. package/dist/lib/signal/graph/derived.mjs +9 -8
  36. package/dist/lib/signal/graph/error-boundary.cjs +3 -2
  37. package/dist/lib/signal/graph/error-boundary.mjs +3 -2
  38. package/dist/lib/signal/graph/index.cjs +2 -2
  39. package/dist/lib/signal/graph/index.mjs +2 -2
  40. package/dist/lib/signal/graph/observe.cjs +38 -3
  41. package/dist/lib/signal/graph/observe.d.ts +44 -0
  42. package/dist/lib/signal/graph/observe.d.ts.map +1 -1
  43. package/dist/lib/signal/graph/observe.js +50 -1
  44. package/dist/lib/signal/graph/observe.mjs +38 -3
  45. package/dist/lib/signal/graph/resource.cjs +9 -8
  46. package/dist/lib/signal/graph/resource.mjs +9 -8
  47. package/dist/lib/signal/graph/runtime.cjs +7 -6
  48. package/dist/lib/signal/graph/runtime.d.ts +1 -1
  49. package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
  50. package/dist/lib/signal/graph/runtime.js +4 -4
  51. package/dist/lib/signal/graph/runtime.mjs +7 -6
  52. package/dist/lib/signal/graph/signal-next.cjs +39 -9
  53. package/dist/lib/signal/graph/signal-next.d.ts +1 -1
  54. package/dist/lib/signal/graph/signal-next.d.ts.map +1 -1
  55. package/dist/lib/signal/graph/signal-next.js +1 -1
  56. package/dist/lib/signal/graph/signal-next.mjs +39 -9
  57. package/dist/lib/signal/graph/ssr-hooks.cjs +29 -0
  58. package/dist/lib/signal/graph/ssr-hooks.d.ts +24 -0
  59. package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -1
  60. package/dist/lib/signal/graph/ssr-hooks.js +36 -0
  61. package/dist/lib/signal/graph/ssr-hooks.mjs +29 -0
  62. package/dist/lib/signal/graph/state.cjs +1 -1
  63. package/dist/lib/signal/graph/state.mjs +1 -1
  64. package/dist/lib/signal/graph/suspense.cjs +3 -2
  65. package/dist/lib/signal/graph/suspense.mjs +3 -2
  66. package/dist/lib/signal/index-legacy.cjs +65 -34
  67. package/dist/lib/signal/index-legacy.mjs +65 -34
  68. package/dist/lib/signal/index.cjs +76 -12
  69. package/dist/lib/signal/index.d.ts +2 -1
  70. package/dist/lib/signal/index.d.ts.map +1 -1
  71. package/dist/lib/signal/index.js +1 -1
  72. package/dist/lib/signal/index.mjs +76 -12
  73. package/dist/lib/signal/list.cjs +3 -2
  74. package/dist/lib/signal/list.mjs +3 -2
  75. package/dist/lib/signal/resource-api.cjs +9 -8
  76. package/dist/lib/signal/resource-api.mjs +9 -8
  77. package/dist/lib/signal/signal.cjs +9 -8
  78. package/dist/lib/signal/signal.mjs +9 -8
  79. package/dist/lib/signal/utilities.cjs +10 -9
  80. package/dist/lib/signal/utilities.mjs +10 -9
  81. package/dist/lib/store/api.cjs +3 -2
  82. package/dist/lib/store/api.mjs +3 -2
  83. package/dist/lib/store/index.cjs +4 -3
  84. package/dist/lib/store/index.mjs +4 -3
  85. package/dist/lib/store/store.cjs +3 -2
  86. package/dist/lib/store/store.mjs +3 -2
  87. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  88. package/dist/version.generated.cjs +2 -2
  89. package/dist/version.generated.d.ts +1 -1
  90. package/dist/version.generated.js +1 -1
  91. package/dist/version.generated.mjs +2 -2
  92. package/package.json +2 -2
@@ -24,4 +24,28 @@ export declare function nextResourceId(): string | undefined;
24
24
  export declare function setResourceDataSink(fn: ((id: string, value: any) => void) | null): void;
25
25
  /** @internal, a resource reports its resolved value here. */
26
26
  export declare function reportResourceData(id: string, value: any): void;
27
+ /** Where cached resources keep their entries and in-flight fetches. */
28
+ export interface ResourceCacheEntry {
29
+ value: unknown;
30
+ /** Date.now() when it was fetched. */
31
+ timestamp: number;
32
+ }
33
+ export interface ResourceCache {
34
+ get(key: string): ResourceCacheEntry | undefined;
35
+ set(key: string, entry: ResourceCacheEntry): void;
36
+ delete(key: string): void;
37
+ keys(): Iterable<string>;
38
+ clear(): void;
39
+ /** Fetches running now, by key, so two readers share one request. Same scope as the entries. */
40
+ readonly inflight: Map<string, Promise<unknown>>;
41
+ }
42
+ /** A cache held in memory, values kept as they are (Dates, class instances). */
43
+ export declare function createResourceCache(): ResourceCache;
44
+ /**
45
+ * Inject the cache for the current scope. The server sets one per request, so two visitors
46
+ * never share an entry or an in-flight fetch.
47
+ */
48
+ export declare function setResourceCacheScope(fn: (() => ResourceCache | undefined) | null): void;
49
+ /** The cache for where this runs: the injected scope, else the page in a browser, else a private one. */
50
+ export declare function currentResourceCache(): ResourceCache;
27
51
  //# sourceMappingURL=ssr-hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-hooks.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/ssr-hooks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAE/E;AACD,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAE1D;AAGD,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,IAAI,CAEjG;AACD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAEpE;AAGD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAEnE;AACD,0FAA0F;AAC1F,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAGD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAEvF;AACD,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAE/D"}
1
+ {"version":3,"file":"ssr-hooks.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/ssr-hooks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAE/E;AACD,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAE1D;AAGD,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,IAAI,CAEjG;AACD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,GAAG,CAAA;CAAE,GAAG,SAAS,CAEpE;AAGD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAEnE;AACD,0FAA0F;AAC1F,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAGD,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAEvF;AACD,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAE/D;AAED,uEAAuE;AACvE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzB,KAAK,IAAI,IAAI,CAAC;IACd,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;CAClD;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,aAAa,CAcnD;AAGD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,IAAI,CAExF;AAKD,yGAAyG;AACzG,wBAAgB,oBAAoB,IAAI,aAAa,CAMpD"}
@@ -42,3 +42,39 @@ export function reportResourceData(id, value) {
42
42
  if (_resourceDataSink)
43
43
  _resourceDataSink(id, value);
44
44
  }
45
+ /** A cache held in memory, values kept as they are (Dates, class instances). */
46
+ export function createResourceCache() {
47
+ const entries = new Map();
48
+ const inflight = new Map();
49
+ return {
50
+ get: (key) => entries.get(key),
51
+ set: (key, entry) => void entries.set(key, entry),
52
+ delete: (key) => void entries.delete(key),
53
+ keys: () => entries.keys(),
54
+ clear: () => {
55
+ entries.clear();
56
+ inflight.clear();
57
+ },
58
+ inflight,
59
+ };
60
+ }
61
+ let _cacheScope = null;
62
+ /**
63
+ * Inject the cache for the current scope. The server sets one per request, so two visitors
64
+ * never share an entry or an in-flight fetch.
65
+ */
66
+ export function setResourceCacheScope(fn) {
67
+ _cacheScope = fn;
68
+ }
69
+ // The browser serves one user, so the page is the scope there.
70
+ let _pageCache;
71
+ /** The cache for where this runs: the injected scope, else the page in a browser, else a private one. */
72
+ export function currentResourceCache() {
73
+ const scoped = _cacheScope?.();
74
+ if (scoped)
75
+ return scoped;
76
+ // A server with no scope injected: nothing safe to share, so nothing is shared.
77
+ if (typeof window === 'undefined')
78
+ return createResourceCache();
79
+ return (_pageCache ??= createResourceCache());
80
+ }
@@ -27,10 +27,39 @@ function setResourceDataSink(fn) {
27
27
  function reportResourceData(id, value) {
28
28
  if (_resourceDataSink) _resourceDataSink(id, value);
29
29
  }
30
+ function createResourceCache() {
31
+ const entries = /* @__PURE__ */ new Map();
32
+ const inflight = /* @__PURE__ */ new Map();
33
+ return {
34
+ get: (key) => entries.get(key),
35
+ set: (key, entry) => void entries.set(key, entry),
36
+ delete: (key) => void entries.delete(key),
37
+ keys: () => entries.keys(),
38
+ clear: () => {
39
+ entries.clear();
40
+ inflight.clear();
41
+ },
42
+ inflight
43
+ };
44
+ }
45
+ var _cacheScope = null;
46
+ function setResourceCacheScope(fn) {
47
+ _cacheScope = fn;
48
+ }
49
+ var _pageCache;
50
+ function currentResourceCache() {
51
+ const scoped = _cacheScope?.();
52
+ if (scoped) return scoped;
53
+ if (typeof window === "undefined") return createResourceCache();
54
+ return _pageCache ??= createResourceCache();
55
+ }
30
56
  export {
57
+ createResourceCache,
58
+ currentResourceCache,
31
59
  getServerData,
32
60
  nextResourceId,
33
61
  reportResourceData,
62
+ setResourceCacheScope,
34
63
  setResourceDataSink,
35
64
  setResourceIdSource,
36
65
  setResourceTracker,
@@ -27,7 +27,7 @@ __export(state_exports, {
27
27
  module.exports = __toCommonJS(state_exports);
28
28
 
29
29
  // src/version.generated.ts
30
- var VERSION = "1.0.0-alpha.92";
30
+ var VERSION = "1.0.0-alpha.94";
31
31
 
32
32
  // src/lib/signal/graph/state.ts
33
33
  var MAJOR = VERSION.split(".")[0];
@@ -1,5 +1,5 @@
1
1
  // src/version.generated.ts
2
- var VERSION = "1.0.0-alpha.92";
2
+ var VERSION = "1.0.0-alpha.94";
3
3
 
4
4
  // src/lib/signal/graph/state.ts
5
5
  var MAJOR = VERSION.split(".")[0];
@@ -27,7 +27,7 @@ __export(suspense_exports, {
27
27
  module.exports = __toCommonJS(suspense_exports);
28
28
 
29
29
  // src/version.generated.ts
30
- var VERSION = "1.0.0-alpha.92";
30
+ var VERSION = "1.0.0-alpha.94";
31
31
 
32
32
  // src/lib/signal/graph/state.ts
33
33
  var MAJOR = VERSION.split(".")[0];
@@ -77,11 +77,12 @@ function observeReactiveNodes(next) {
77
77
  }
78
78
  var running = [];
79
79
  var origin;
80
+ var currentScope;
80
81
  function reportReactiveNode(report) {
81
82
  const observer = G.observer;
82
83
  if (observer) {
83
84
  observer.created(
84
- report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
85
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin, scope: report.scope ?? currentScope } : { ...report, scope: report.scope ?? currentScope }
85
86
  );
86
87
  }
87
88
  }
@@ -1,5 +1,5 @@
1
1
  // src/version.generated.ts
2
- var VERSION = "1.0.0-alpha.92";
2
+ var VERSION = "1.0.0-alpha.94";
3
3
 
4
4
  // src/lib/signal/graph/state.ts
5
5
  var MAJOR = VERSION.split(".")[0];
@@ -49,11 +49,12 @@ function observeReactiveNodes(next) {
49
49
  }
50
50
  var running = [];
51
51
  var origin;
52
+ var currentScope;
52
53
  function reportReactiveNode(report) {
53
54
  const observer = G.observer;
54
55
  if (observer) {
55
56
  observer.created(
56
- report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
57
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin, scope: report.scope ?? currentScope } : { ...report, scope: report.scope ?? currentScope }
57
58
  );
58
59
  }
59
60
  }
@@ -1,4 +1,4 @@
1
- /*! @fluixi/reactive v1.0.0-alpha.92 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/reactive v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -27,11 +27,10 @@ __export(index_legacy_exports, {
27
27
  $SIGNAL: () => $SIGNAL3,
28
28
  __DEV__: () => __DEV__,
29
29
  batch: () => batch3,
30
- clearAllCachedResources: () => clearAllCachedResources,
31
- clearCachedResourceNamespace: () => clearCachedResourceNamespace,
30
+ cachedResource: () => cachedResource,
31
+ clearCachedResources: () => clearCachedResources,
32
32
  combineSignal: () => combineSignal,
33
33
  combineSignals: () => combineSignals,
34
- createCachedResource: () => createCachedResource,
35
34
  createComputed: () => createComputed,
36
35
  createContext: () => createContext,
37
36
  createDebounce: () => createDebounce,
@@ -41,6 +40,7 @@ __export(index_legacy_exports, {
41
40
  createProvider: () => createProvider,
42
41
  createRenderEffect: () => createRenderEffect,
43
42
  createResource: () => createResource,
43
+ createResourceCache: () => createResourceCache,
44
44
  createRoot: () => createRoot2,
45
45
  createSelector: () => createSelector,
46
46
  createSignal: () => createSignal2,
@@ -494,7 +494,7 @@ function makeArrayFlat(values) {
494
494
  }
495
495
 
496
496
  // src/version.generated.ts
497
- var VERSION = "1.0.0-alpha.92";
497
+ var VERSION = "1.0.0-alpha.94";
498
498
 
499
499
  // src/lib/signal/graph/state.ts
500
500
  var MAJOR = VERSION.split(".")[0];
@@ -544,11 +544,12 @@ function observeReactiveNodes(next) {
544
544
  }
545
545
  var running = [];
546
546
  var origin;
547
+ var currentScope;
547
548
  function reportReactiveNode(report) {
548
549
  const observer = G.observer;
549
550
  if (observer) {
550
551
  observer.created(
551
- report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
552
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin, scope: report.scope ?? currentScope } : { ...report, scope: report.scope ?? currentScope }
552
553
  );
553
554
  }
554
555
  }
@@ -863,7 +864,7 @@ function batch(fn) {
863
864
  }
864
865
  }
865
866
  var EffectNode = class {
866
- constructor(fn, report = false) {
867
+ constructor(fn, report = false, name) {
867
868
  this.queued = false;
868
869
  this.disposed = false;
869
870
  this.owner = makeOwner(G.owner);
@@ -875,7 +876,7 @@ var EffectNode = class {
875
876
  if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
876
877
  });
877
878
  });
878
- reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report });
879
+ reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
879
880
  this.watcher = new Watcher(() => enqueue(this));
880
881
  this.run();
881
882
  this.watcher.watch(this.computed);
@@ -902,8 +903,8 @@ var EffectNode = class {
902
903
  disposeOwner(this.owner);
903
904
  }
904
905
  };
905
- function effect(fn, report = false) {
906
- const node = new EffectNode(fn, report);
906
+ function effect(fn, report = false, name) {
907
+ const node = new EffectNode(fn, report, name);
907
908
  return () => node.dispose();
908
909
  }
909
910
 
@@ -971,12 +972,12 @@ function createMemo(fn, value, options) {
971
972
  if (isObserved()) onCleanup(() => reportReactiveDispose(c));
972
973
  return read;
973
974
  }
974
- function createEffect(fn, value) {
975
+ function createEffect(fn, value, options) {
975
976
  let prev = value;
976
977
  return effect(() => {
977
978
  const r = fn(prev);
978
979
  prev = r;
979
- }, true);
980
+ }, true, options?.name);
980
981
  }
981
982
  function batch2(fn) {
982
983
  return batch(fn);
@@ -1085,6 +1086,29 @@ function setResourceDataSink(fn) {
1085
1086
  function reportResourceData(id, value) {
1086
1087
  if (_resourceDataSink) _resourceDataSink(id, value);
1087
1088
  }
1089
+ function createResourceCache() {
1090
+ const entries = /* @__PURE__ */ new Map();
1091
+ const inflight = /* @__PURE__ */ new Map();
1092
+ return {
1093
+ get: (key) => entries.get(key),
1094
+ set: (key, entry) => void entries.set(key, entry),
1095
+ delete: (key) => void entries.delete(key),
1096
+ keys: () => entries.keys(),
1097
+ clear: () => {
1098
+ entries.clear();
1099
+ inflight.clear();
1100
+ },
1101
+ inflight
1102
+ };
1103
+ }
1104
+ var _cacheScope = null;
1105
+ var _pageCache;
1106
+ function currentResourceCache() {
1107
+ const scoped = _cacheScope?.();
1108
+ if (scoped) return scoped;
1109
+ if (typeof window === "undefined") return createResourceCache();
1110
+ return _pageCache ??= createResourceCache();
1111
+ }
1088
1112
 
1089
1113
  // src/lib/signal/signal.ts
1090
1114
  var $SIGNAL3 = /* @__PURE__ */ Symbol.for("signal");
@@ -2211,12 +2235,10 @@ function readSignal(signal) {
2211
2235
  }
2212
2236
 
2213
2237
  // src/lib/signal/cached-resource.ts
2214
- var ttlCache = /* @__PURE__ */ new Map();
2215
- var inflight = /* @__PURE__ */ new Map();
2216
2238
  var _autoId = 0;
2217
2239
  var $SIGNAL4 = /* @__PURE__ */ Symbol.for("signal");
2218
2240
  var $RESOURCE3 = /* @__PURE__ */ Symbol.for("resource");
2219
- function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2241
+ function cachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2220
2242
  let sourceFn;
2221
2243
  let fetchFn;
2222
2244
  let options;
@@ -2235,7 +2257,13 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2235
2257
  staleWhileRevalidate = true
2236
2258
  } = options;
2237
2259
  const ns = name;
2238
- const buildKey = (key) => `${ns}:${JSON.stringify(key)}`;
2260
+ const cache = options.cache ?? currentResourceCache();
2261
+ const inflight = cache.inflight;
2262
+ const ssrId = options.transport === false ? void 0 : nextResourceId();
2263
+ const seed = ssrId !== void 0 ? getServerData(ssrId) : void 0;
2264
+ const deps = options.deps ?? [];
2265
+ const depValues = () => deps.map((dep) => dep());
2266
+ const buildKey = (key, values = untrack2(depValues)) => `${ns}:${JSON.stringify(key)}` + (deps.length ? `:${JSON.stringify(values)}` : "");
2239
2267
  const isFresh = (entry) => ttl === Infinity || Date.now() - entry.timestamp <= ttl;
2240
2268
  const [value, setValue] = createSignal(void 0, { equals: false });
2241
2269
  const [resourceState, setResourceState] = createSignal("unresolved", { equals: false });
@@ -2248,8 +2276,9 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2248
2276
  let flagRefetch = false;
2249
2277
  let flagInvalidate = false;
2250
2278
  function doFetch(key, ck, background, isCancelled) {
2251
- if (inflight.has(ck)) {
2252
- inflight.get(ck).then(
2279
+ const running2 = inflight.get(ck);
2280
+ if (running2) {
2281
+ running2.then(
2253
2282
  (v) => {
2254
2283
  if (!isCancelled()) settle(v, background);
2255
2284
  },
@@ -2257,12 +2286,15 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2257
2286
  if (!isCancelled() && !background) fail(e);
2258
2287
  }
2259
2288
  );
2260
- if (!background) setPendingP(inflight.get(ck));
2289
+ if (!background) {
2290
+ trackResourcePromise(running2);
2291
+ setPendingP(running2);
2292
+ }
2261
2293
  return;
2262
2294
  }
2263
2295
  const promise = Promise.resolve(fetchFn(key)).then(
2264
2296
  (v) => {
2265
- ttlCache.set(ck, { value: v, timestamp: Date.now() });
2297
+ cache.set(ck, { value: v, timestamp: Date.now() });
2266
2298
  inflight.delete(ck);
2267
2299
  return v;
2268
2300
  },
@@ -2285,7 +2317,8 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2285
2317
  }
2286
2318
  );
2287
2319
  }
2288
- function settle(v, background) {
2320
+ function settle(v, _background) {
2321
+ if (ssrId !== void 0) reportResourceData(ssrId, v);
2289
2322
  batch2(() => {
2290
2323
  setValue(() => v);
2291
2324
  setResourceState("ready");
@@ -2303,6 +2336,7 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2303
2336
  }
2304
2337
  createEffect(() => {
2305
2338
  const key = sourceFn();
2339
+ const values = depValues();
2306
2340
  tick();
2307
2341
  if (key === false || key === null || key === void 0) {
2308
2342
  prevKey = UNSET;
@@ -2317,16 +2351,18 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2317
2351
  const doInvalidate = flagInvalidate;
2318
2352
  flagRefetch = false;
2319
2353
  flagInvalidate = false;
2320
- const ck = buildKey(key);
2321
- if (doInvalidate) ttlCache.delete(ck);
2354
+ const ck = buildKey(key, values);
2355
+ if (seed && prevKey === UNSET && !cache.get(ck)) cache.set(ck, { value: seed.value, timestamp: Date.now() });
2356
+ if (doInvalidate) cache.delete(ck);
2322
2357
  const keyChanged = prevKey === UNSET || key !== prevKey;
2323
2358
  prevKey = key;
2324
2359
  let cancelled = false;
2325
2360
  onCleanup(() => {
2326
2361
  cancelled = true;
2327
2362
  });
2328
- const cached = ttlCache.get(ck);
2363
+ const cached = cache.get(ck);
2329
2364
  if (cached && isFresh(cached) && !doRefetch && !doInvalidate) {
2365
+ if (ssrId !== void 0) reportResourceData(ssrId, cached.value);
2330
2366
  const cur2 = untrack2(resourceState);
2331
2367
  if (cur2 !== "ready" || untrack2(value) !== cached.value) {
2332
2368
  batch2(() => {
@@ -2387,22 +2423,17 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2387
2423
  const invalidate = () => {
2388
2424
  const key = untrack2(sourceFn);
2389
2425
  if (key !== null && key !== void 0 && key !== false) {
2390
- ttlCache.delete(buildKey(key));
2426
+ cache.delete(buildKey(key));
2391
2427
  }
2392
2428
  flagInvalidate = true;
2393
2429
  setTick((v) => v + 1);
2394
2430
  };
2395
- return [resource, { mutate: setValue, refetch, invalidate }];
2431
+ return Object.assign(resource, { mutate: setValue, refetch, invalidate });
2396
2432
  }
2397
- function clearCachedResourceNamespace(name) {
2433
+ function clearCachedResources(name, cache = currentResourceCache()) {
2434
+ if (name === void 0) return cache.clear();
2398
2435
  const prefix = `${name}:`;
2399
- for (const key of ttlCache.keys()) {
2400
- if (key.startsWith(prefix)) ttlCache.delete(key);
2401
- }
2402
- }
2403
- function clearAllCachedResources() {
2404
- ttlCache.clear();
2405
- inflight.clear();
2436
+ for (const key of [...cache.keys()]) if (key.startsWith(prefix)) cache.delete(key);
2406
2437
  }
2407
2438
 
2408
2439
  // src/lib/signal/list.ts
@@ -1,4 +1,4 @@
1
- /*! @fluixi/reactive v1.0.0-alpha.92 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/reactive v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/lib/predicates.ts
4
4
  function isFunction(value) {
@@ -392,7 +392,7 @@ function makeArrayFlat(values) {
392
392
  }
393
393
 
394
394
  // src/version.generated.ts
395
- var VERSION = "1.0.0-alpha.92";
395
+ var VERSION = "1.0.0-alpha.94";
396
396
 
397
397
  // src/lib/signal/graph/state.ts
398
398
  var MAJOR = VERSION.split(".")[0];
@@ -442,11 +442,12 @@ function observeReactiveNodes(next) {
442
442
  }
443
443
  var running = [];
444
444
  var origin;
445
+ var currentScope;
445
446
  function reportReactiveNode(report) {
446
447
  const observer = G.observer;
447
448
  if (observer) {
448
449
  observer.created(
449
- report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
450
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin, scope: report.scope ?? currentScope } : { ...report, scope: report.scope ?? currentScope }
450
451
  );
451
452
  }
452
453
  }
@@ -761,7 +762,7 @@ function batch(fn) {
761
762
  }
762
763
  }
763
764
  var EffectNode = class {
764
- constructor(fn, report = false) {
765
+ constructor(fn, report = false, name) {
765
766
  this.queued = false;
766
767
  this.disposed = false;
767
768
  this.owner = makeOwner(G.owner);
@@ -773,7 +774,7 @@ var EffectNode = class {
773
774
  if (typeof r === "function") (this.owner.cleanups ??= []).push(r);
774
775
  });
775
776
  });
776
- reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report });
777
+ reportReactiveNode({ kind: "effect", node: this.computed, handle: this, internal: !report, ...name ? { name } : {} });
777
778
  this.watcher = new Watcher(() => enqueue(this));
778
779
  this.run();
779
780
  this.watcher.watch(this.computed);
@@ -800,8 +801,8 @@ var EffectNode = class {
800
801
  disposeOwner(this.owner);
801
802
  }
802
803
  };
803
- function effect(fn, report = false) {
804
- const node = new EffectNode(fn, report);
804
+ function effect(fn, report = false, name) {
805
+ const node = new EffectNode(fn, report, name);
805
806
  return () => node.dispose();
806
807
  }
807
808
 
@@ -869,12 +870,12 @@ function createMemo(fn, value, options) {
869
870
  if (isObserved()) onCleanup(() => reportReactiveDispose(c));
870
871
  return read;
871
872
  }
872
- function createEffect(fn, value) {
873
+ function createEffect(fn, value, options) {
873
874
  let prev = value;
874
875
  return effect(() => {
875
876
  const r = fn(prev);
876
877
  prev = r;
877
- }, true);
878
+ }, true, options?.name);
878
879
  }
879
880
  function batch2(fn) {
880
881
  return batch(fn);
@@ -983,6 +984,29 @@ function setResourceDataSink(fn) {
983
984
  function reportResourceData(id, value) {
984
985
  if (_resourceDataSink) _resourceDataSink(id, value);
985
986
  }
987
+ function createResourceCache() {
988
+ const entries = /* @__PURE__ */ new Map();
989
+ const inflight = /* @__PURE__ */ new Map();
990
+ return {
991
+ get: (key) => entries.get(key),
992
+ set: (key, entry) => void entries.set(key, entry),
993
+ delete: (key) => void entries.delete(key),
994
+ keys: () => entries.keys(),
995
+ clear: () => {
996
+ entries.clear();
997
+ inflight.clear();
998
+ },
999
+ inflight
1000
+ };
1001
+ }
1002
+ var _cacheScope = null;
1003
+ var _pageCache;
1004
+ function currentResourceCache() {
1005
+ const scoped = _cacheScope?.();
1006
+ if (scoped) return scoped;
1007
+ if (typeof window === "undefined") return createResourceCache();
1008
+ return _pageCache ??= createResourceCache();
1009
+ }
986
1010
 
987
1011
  // src/lib/signal/signal.ts
988
1012
  var $SIGNAL3 = /* @__PURE__ */ Symbol.for("signal");
@@ -2109,12 +2133,10 @@ function readSignal(signal) {
2109
2133
  }
2110
2134
 
2111
2135
  // src/lib/signal/cached-resource.ts
2112
- var ttlCache = /* @__PURE__ */ new Map();
2113
- var inflight = /* @__PURE__ */ new Map();
2114
2136
  var _autoId = 0;
2115
2137
  var $SIGNAL4 = /* @__PURE__ */ Symbol.for("signal");
2116
2138
  var $RESOURCE3 = /* @__PURE__ */ Symbol.for("resource");
2117
- function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2139
+ function cachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2118
2140
  let sourceFn;
2119
2141
  let fetchFn;
2120
2142
  let options;
@@ -2133,7 +2155,13 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2133
2155
  staleWhileRevalidate = true
2134
2156
  } = options;
2135
2157
  const ns = name;
2136
- const buildKey = (key) => `${ns}:${JSON.stringify(key)}`;
2158
+ const cache = options.cache ?? currentResourceCache();
2159
+ const inflight = cache.inflight;
2160
+ const ssrId = options.transport === false ? void 0 : nextResourceId();
2161
+ const seed = ssrId !== void 0 ? getServerData(ssrId) : void 0;
2162
+ const deps = options.deps ?? [];
2163
+ const depValues = () => deps.map((dep) => dep());
2164
+ const buildKey = (key, values = untrack2(depValues)) => `${ns}:${JSON.stringify(key)}` + (deps.length ? `:${JSON.stringify(values)}` : "");
2137
2165
  const isFresh = (entry) => ttl === Infinity || Date.now() - entry.timestamp <= ttl;
2138
2166
  const [value, setValue] = createSignal(void 0, { equals: false });
2139
2167
  const [resourceState, setResourceState] = createSignal("unresolved", { equals: false });
@@ -2146,8 +2174,9 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2146
2174
  let flagRefetch = false;
2147
2175
  let flagInvalidate = false;
2148
2176
  function doFetch(key, ck, background, isCancelled) {
2149
- if (inflight.has(ck)) {
2150
- inflight.get(ck).then(
2177
+ const running2 = inflight.get(ck);
2178
+ if (running2) {
2179
+ running2.then(
2151
2180
  (v) => {
2152
2181
  if (!isCancelled()) settle(v, background);
2153
2182
  },
@@ -2155,12 +2184,15 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2155
2184
  if (!isCancelled() && !background) fail(e);
2156
2185
  }
2157
2186
  );
2158
- if (!background) setPendingP(inflight.get(ck));
2187
+ if (!background) {
2188
+ trackResourcePromise(running2);
2189
+ setPendingP(running2);
2190
+ }
2159
2191
  return;
2160
2192
  }
2161
2193
  const promise = Promise.resolve(fetchFn(key)).then(
2162
2194
  (v) => {
2163
- ttlCache.set(ck, { value: v, timestamp: Date.now() });
2195
+ cache.set(ck, { value: v, timestamp: Date.now() });
2164
2196
  inflight.delete(ck);
2165
2197
  return v;
2166
2198
  },
@@ -2183,7 +2215,8 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2183
2215
  }
2184
2216
  );
2185
2217
  }
2186
- function settle(v, background) {
2218
+ function settle(v, _background) {
2219
+ if (ssrId !== void 0) reportResourceData(ssrId, v);
2187
2220
  batch2(() => {
2188
2221
  setValue(() => v);
2189
2222
  setResourceState("ready");
@@ -2201,6 +2234,7 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2201
2234
  }
2202
2235
  createEffect(() => {
2203
2236
  const key = sourceFn();
2237
+ const values = depValues();
2204
2238
  tick();
2205
2239
  if (key === false || key === null || key === void 0) {
2206
2240
  prevKey = UNSET;
@@ -2215,16 +2249,18 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2215
2249
  const doInvalidate = flagInvalidate;
2216
2250
  flagRefetch = false;
2217
2251
  flagInvalidate = false;
2218
- const ck = buildKey(key);
2219
- if (doInvalidate) ttlCache.delete(ck);
2252
+ const ck = buildKey(key, values);
2253
+ if (seed && prevKey === UNSET && !cache.get(ck)) cache.set(ck, { value: seed.value, timestamp: Date.now() });
2254
+ if (doInvalidate) cache.delete(ck);
2220
2255
  const keyChanged = prevKey === UNSET || key !== prevKey;
2221
2256
  prevKey = key;
2222
2257
  let cancelled = false;
2223
2258
  onCleanup(() => {
2224
2259
  cancelled = true;
2225
2260
  });
2226
- const cached = ttlCache.get(ck);
2261
+ const cached = cache.get(ck);
2227
2262
  if (cached && isFresh(cached) && !doRefetch && !doInvalidate) {
2263
+ if (ssrId !== void 0) reportResourceData(ssrId, cached.value);
2228
2264
  const cur2 = untrack2(resourceState);
2229
2265
  if (cur2 !== "ready" || untrack2(value) !== cached.value) {
2230
2266
  batch2(() => {
@@ -2285,22 +2321,17 @@ function createCachedResource(sourceOrFetcher, fetcherOrOptions, opts = {}) {
2285
2321
  const invalidate = () => {
2286
2322
  const key = untrack2(sourceFn);
2287
2323
  if (key !== null && key !== void 0 && key !== false) {
2288
- ttlCache.delete(buildKey(key));
2324
+ cache.delete(buildKey(key));
2289
2325
  }
2290
2326
  flagInvalidate = true;
2291
2327
  setTick((v) => v + 1);
2292
2328
  };
2293
- return [resource, { mutate: setValue, refetch, invalidate }];
2329
+ return Object.assign(resource, { mutate: setValue, refetch, invalidate });
2294
2330
  }
2295
- function clearCachedResourceNamespace(name) {
2331
+ function clearCachedResources(name, cache = currentResourceCache()) {
2332
+ if (name === void 0) return cache.clear();
2296
2333
  const prefix = `${name}:`;
2297
- for (const key of ttlCache.keys()) {
2298
- if (key.startsWith(prefix)) ttlCache.delete(key);
2299
- }
2300
- }
2301
- function clearAllCachedResources() {
2302
- ttlCache.clear();
2303
- inflight.clear();
2334
+ for (const key of [...cache.keys()]) if (key.startsWith(prefix)) cache.delete(key);
2304
2335
  }
2305
2336
 
2306
2337
  // src/lib/signal/list.ts
@@ -2443,11 +2474,10 @@ export {
2443
2474
  $SIGNAL3 as $SIGNAL,
2444
2475
  __DEV__,
2445
2476
  batch3 as batch,
2446
- clearAllCachedResources,
2447
- clearCachedResourceNamespace,
2477
+ cachedResource,
2478
+ clearCachedResources,
2448
2479
  combineSignal,
2449
2480
  combineSignals,
2450
- createCachedResource,
2451
2481
  createComputed,
2452
2482
  createContext,
2453
2483
  createDebounce,
@@ -2457,6 +2487,7 @@ export {
2457
2487
  createProvider,
2458
2488
  createRenderEffect,
2459
2489
  createResource,
2490
+ createResourceCache,
2460
2491
  createRoot2 as createRoot,
2461
2492
  createSelector,
2462
2493
  createSignal2 as createSignal,