signalium 2.1.3 → 2.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # signalium
2
2
 
3
+ ## 2.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 2cf6766: Add forwardRelay utility
8
+
3
9
  ## 2.1.3
4
10
 
5
11
  ### Patch Changes
@@ -4,5 +4,5 @@ export { signal, notifier } from './internals/signal.js';
4
4
  export { ReactivePromise } from './internals/async.js';
5
5
  export { callback } from './internals/callback.js';
6
6
  export { context, getContext, withContexts, setGlobalContexts, clearGlobalContexts, setScopeOwner, } from './internals/contexts.js';
7
- export { watchOnce } from './utils.js';
7
+ export { watchOnce, forwardRelay } from './utils.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,4BAA4B,EACjC,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,4BAA4B,EACjC,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.watchOnce = exports.setScopeOwner = exports.clearGlobalContexts = exports.setGlobalContexts = exports.withContexts = exports.getContext = exports.context = exports.callback = exports.ReactivePromise = exports.notifier = exports.signal = exports.watcher = exports.relay = exports.task = exports.reactiveSignal = exports.reactiveMethod = exports.reactive = void 0;
3
+ exports.forwardRelay = exports.watchOnce = exports.setScopeOwner = exports.clearGlobalContexts = exports.setGlobalContexts = exports.withContexts = exports.getContext = exports.context = exports.callback = exports.ReactivePromise = exports.notifier = exports.signal = exports.watcher = exports.relay = exports.task = exports.reactiveSignal = exports.reactiveMethod = exports.reactive = void 0;
4
4
  var core_api_js_1 = require("./internals/core-api.js");
5
5
  Object.defineProperty(exports, "reactive", { enumerable: true, get: function () { return core_api_js_1.reactive; } });
6
6
  Object.defineProperty(exports, "reactiveMethod", { enumerable: true, get: function () { return core_api_js_1.reactiveMethod; } });
@@ -24,4 +24,5 @@ Object.defineProperty(exports, "clearGlobalContexts", { enumerable: true, get: f
24
24
  Object.defineProperty(exports, "setScopeOwner", { enumerable: true, get: function () { return contexts_js_1.setScopeOwner; } });
25
25
  var utils_js_1 = require("./utils.js");
26
26
  Object.defineProperty(exports, "watchOnce", { enumerable: true, get: function () { return utils_js_1.watchOnce; } });
27
+ Object.defineProperty(exports, "forwardRelay", { enumerable: true, get: function () { return utils_js_1.forwardRelay; } });
27
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAoBA,uDAAyG;AAAhG,uGAAA,QAAQ,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,mGAAA,IAAI,OAAA;AAAE,oGAAA,KAAK,OAAA;AAAE,sGAAA,OAAO,OAAA;AAEvE,mDAAyD;AAAhD,mGAAA,MAAM,OAAA;AAAE,qGAAA,QAAQ,OAAA;AAEzB,iDAAuD;AAA9C,2GAAA,eAAe,OAAA;AAExB,uDAAmD;AAA1C,uGAAA,QAAQ,OAAA;AAEjB,uDAOiC;AAN/B,sGAAA,OAAO,OAAA;AACP,yGAAA,UAAU,OAAA;AACV,2GAAA,YAAY,OAAA;AACZ,gHAAA,iBAAiB,OAAA;AACjB,kHAAA,mBAAmB,OAAA;AACnB,4GAAA,aAAa,OAAA;AAGf,uCAAuC;AAA9B,qGAAA,SAAS,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAoBA,uDAAyG;AAAhG,uGAAA,QAAQ,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,6GAAA,cAAc,OAAA;AAAE,mGAAA,IAAI,OAAA;AAAE,oGAAA,KAAK,OAAA;AAAE,sGAAA,OAAO,OAAA;AAEvE,mDAAyD;AAAhD,mGAAA,MAAM,OAAA;AAAE,qGAAA,QAAQ,OAAA;AAEzB,iDAAuD;AAA9C,2GAAA,eAAe,OAAA;AAExB,uDAAmD;AAA1C,uGAAA,QAAQ,OAAA;AAEjB,uDAOiC;AAN/B,sGAAA,OAAO,OAAA;AACP,yGAAA,UAAU,OAAA;AACV,2GAAA,YAAY,OAAA;AACZ,gHAAA,iBAAiB,OAAA;AACjB,kHAAA,mBAAmB,OAAA;AACnB,4GAAA,aAAa,OAAA;AAGf,uCAAqD;AAA5C,qGAAA,SAAS,OAAA;AAAE,wGAAA,YAAY,OAAA"}
@@ -1,4 +1,5 @@
1
1
  export { hashValue, registerCustomHash } from './internals/utils/hash.js';
2
+ import { RelayState, DiscriminatedReactivePromise } from './types.js';
2
3
  /**
3
4
  * Watches a function once in a reactive context, activating any relays,
4
5
  * then automatically tears down the watcher when complete.
@@ -23,4 +24,35 @@ export { hashValue, registerCustomHash } from './internals/utils/hash.js';
23
24
  */
24
25
  export declare function watchOnce<T>(fn: () => T): T;
25
26
  export { setReactivePromise } from './internals/async.js';
27
+ /**
28
+ * Forwards state from a source relay to the target relay's state.
29
+ * This enables composition patterns where relays can add side effects
30
+ * while transparently forwarding state from another relay.
31
+ *
32
+ * The forwarding is automatically tracked through the signal graph.
33
+ * When the source relay updates, the target relay will re-run its
34
+ * activation function, and forwardRelay will forward the new state.
35
+ * No cleanup is needed - dependencies are managed automatically.
36
+ *
37
+ * @param state - The target relay's state object
38
+ * @param sourceRelay - The source relay to forward state from
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const sourceRelay = relay(state => {
43
+ * // ... source relay logic
44
+ * });
45
+ *
46
+ * const forwardedRelay = relay(state => {
47
+ * // Add additional side effect
48
+ * const cleanup = setupSomeEffect();
49
+ *
50
+ * // Forward state from source relay (automatically tracked and cleaned up)
51
+ * forwardRelay(state, sourceRelay);
52
+ *
53
+ * return cleanup; // Only return cleanup for the additional effect
54
+ * });
55
+ * ```
56
+ */
57
+ export declare function forwardRelay<T>(state: RelayState<T>, sourceRelay: DiscriminatedReactivePromise<T>): void;
26
58
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAW1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAwB3C;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ1E,OAAO,EAAiB,UAAU,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAwB3C;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,IAAI,CA8BxG"}
package/dist/cjs/utils.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setReactivePromise = exports.registerCustomHash = exports.hashValue = void 0;
4
4
  exports.watchOnce = watchOnce;
5
+ exports.forwardRelay = forwardRelay;
5
6
  var hash_js_1 = require("./internals/utils/hash.js");
6
7
  Object.defineProperty(exports, "hashValue", { enumerable: true, get: function () { return hash_js_1.hashValue; } });
7
8
  Object.defineProperty(exports, "registerCustomHash", { enumerable: true, get: function () { return hash_js_1.registerCustomHash; } });
@@ -57,4 +58,66 @@ function watchOnce(fn) {
57
58
  }
58
59
  var async_js_2 = require("./internals/async.js");
59
60
  Object.defineProperty(exports, "setReactivePromise", { enumerable: true, get: function () { return async_js_2.setReactivePromise; } });
61
+ /**
62
+ * Forwards state from a source relay to the target relay's state.
63
+ * This enables composition patterns where relays can add side effects
64
+ * while transparently forwarding state from another relay.
65
+ *
66
+ * The forwarding is automatically tracked through the signal graph.
67
+ * When the source relay updates, the target relay will re-run its
68
+ * activation function, and forwardRelay will forward the new state.
69
+ * No cleanup is needed - dependencies are managed automatically.
70
+ *
71
+ * @param state - The target relay's state object
72
+ * @param sourceRelay - The source relay to forward state from
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const sourceRelay = relay(state => {
77
+ * // ... source relay logic
78
+ * });
79
+ *
80
+ * const forwardedRelay = relay(state => {
81
+ * // Add additional side effect
82
+ * const cleanup = setupSomeEffect();
83
+ *
84
+ * // Forward state from source relay (automatically tracked and cleaned up)
85
+ * forwardRelay(state, sourceRelay);
86
+ *
87
+ * return cleanup; // Only return cleanup for the additional effect
88
+ * });
89
+ * ```
90
+ */
91
+ function forwardRelay(state, sourceRelay) {
92
+ // Verify that sourceRelay is actually a ReactivePromiseImpl
93
+ if (!(0, async_js_1.isReactivePromise)(sourceRelay)) {
94
+ throw new Error('forwardRelay: sourceRelay must be a ReactivePromise');
95
+ }
96
+ // Read from source relay to establish dependency and forward state
97
+ // When sourceRelay updates, this relay's activation function will be called again,
98
+ // and forwardRelay will be called again, forwarding the new state
99
+ if (sourceRelay.isPending) {
100
+ // For pending state, try to forward the promise if available
101
+ // Accessing isPending establishes the dependency
102
+ const source = sourceRelay;
103
+ const promise = source['_promise'];
104
+ if (promise) {
105
+ state.setPromise(promise);
106
+ }
107
+ }
108
+ else if (sourceRelay.isRejected) {
109
+ // Accessing error establishes dependency and forwards it
110
+ const error = sourceRelay.error;
111
+ if (error !== undefined) {
112
+ state.setError(error);
113
+ }
114
+ }
115
+ else if (sourceRelay.isResolved && sourceRelay.isReady) {
116
+ // Accessing value establishes dependency and forwards it
117
+ const value = sourceRelay.value;
118
+ if (value !== undefined) {
119
+ state.value = value;
120
+ }
121
+ }
122
+ }
60
123
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;AAiCA,8BAwBC;AAzDD,qDAA0E;AAAjE,oGAAA,SAAS,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAEtC,yDAAkD;AAClD,mDAAkE;AAClE,+CAA+C;AAC/C,mDAA0E;AAG1E,mEAA4D;AAG5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,SAAS,CAAI,EAAW;IACtC,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAA,qBAAO,EAAC,EAAE,CAAiC,CAAC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,IAAA,sBAAW,EAAC,MAAM,CAAC,CAAC;QAEpB,yCAAyC;QACzC,IAAI,MAAM,GAAG,IAAA,kBAAS,EAAC,MAAM,CAAC,CAAC;QAE/B,IAAI,IAAA,4BAAiB,EAAC,MAAgB,CAAC,IAAI,IAAA,yBAAS,EAAC,MAAgB,CAAC,EAAE,CAAC;YACvE,MAAM,GAAI,MAAqB,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC3C,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;YACxB,CAAC,CAAqB,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,iDAA0D;AAAjD,8GAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;AAgCA,8BAwBC;AAkCD,oCA8BC;AAxHD,qDAA0E;AAAjE,oGAAA,SAAS,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAEtC,yDAA4D;AAC5D,mDAAkE;AAClE,+CAA+C;AAC/C,mDAA8E;AAE9E,mEAA4D;AAG5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,SAAS,CAAI,EAAW;IACtC,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAA,qBAAO,EAAC,EAAE,CAAiC,CAAC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,IAAA,sBAAW,EAAC,MAAM,CAAC,CAAC;QAEpB,yCAAyC;QACzC,IAAI,MAAM,GAAG,IAAA,kBAAS,EAAC,MAAM,CAAC,CAAC;QAE/B,IAAI,IAAA,4BAAiB,EAAC,MAAgB,CAAC,IAAI,IAAA,yBAAS,EAAC,MAAgB,CAAC,EAAE,CAAC;YACvE,MAAM,GAAI,MAAqB,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC3C,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;YACxB,CAAC,CAAqB,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,iDAA0D;AAAjD,8GAAA,kBAAkB,OAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAgB,YAAY,CAAI,KAAoB,EAAE,WAA4C;IAChG,4DAA4D;IAC5D,IAAI,CAAC,IAAA,4BAAiB,EAAC,WAAW,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,mEAAmE;IACnE,mFAAmF;IACnF,kEAAkE;IAClE,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1B,6DAA6D;QAC7D,iDAAiD;QACjD,MAAM,MAAM,GAAG,WAAqC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAA2B,CAAC;QAC7D,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAClC,yDAAyD;QACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzD,yDAAyD;QACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -4,5 +4,5 @@ export { signal, notifier } from './internals/signal.js';
4
4
  export { ReactivePromise } from './internals/async.js';
5
5
  export { callback } from './internals/callback.js';
6
6
  export { context, getContext, withContexts, setGlobalContexts, clearGlobalContexts, setScopeOwner, } from './internals/contexts.js';
7
- export { watchOnce } from './utils.js';
7
+ export { watchOnce, forwardRelay } from './utils.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,4BAA4B,EACjC,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,4BAA4B,EACjC,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/esm/index.js CHANGED
@@ -3,5 +3,5 @@ export { signal, notifier } from './internals/signal.js';
3
3
  export { ReactivePromise } from './internals/async.js';
4
4
  export { callback } from './internals/callback.js';
5
5
  export { context, getContext, withContexts, setGlobalContexts, clearGlobalContexts, setScopeOwner, } from './internals/contexts.js';
6
- export { watchOnce } from './utils.js';
6
+ export { watchOnce, forwardRelay } from './utils.js';
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEzG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,OAAO,EACL,OAAO,EACP,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { hashValue, registerCustomHash } from './internals/utils/hash.js';
2
+ import { RelayState, DiscriminatedReactivePromise } from './types.js';
2
3
  /**
3
4
  * Watches a function once in a reactive context, activating any relays,
4
5
  * then automatically tears down the watcher when complete.
@@ -23,4 +24,35 @@ export { hashValue, registerCustomHash } from './internals/utils/hash.js';
23
24
  */
24
25
  export declare function watchOnce<T>(fn: () => T): T;
25
26
  export { setReactivePromise } from './internals/async.js';
27
+ /**
28
+ * Forwards state from a source relay to the target relay's state.
29
+ * This enables composition patterns where relays can add side effects
30
+ * while transparently forwarding state from another relay.
31
+ *
32
+ * The forwarding is automatically tracked through the signal graph.
33
+ * When the source relay updates, the target relay will re-run its
34
+ * activation function, and forwardRelay will forward the new state.
35
+ * No cleanup is needed - dependencies are managed automatically.
36
+ *
37
+ * @param state - The target relay's state object
38
+ * @param sourceRelay - The source relay to forward state from
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const sourceRelay = relay(state => {
43
+ * // ... source relay logic
44
+ * });
45
+ *
46
+ * const forwardedRelay = relay(state => {
47
+ * // Add additional side effect
48
+ * const cleanup = setupSomeEffect();
49
+ *
50
+ * // Forward state from source relay (automatically tracked and cleaned up)
51
+ * forwardRelay(state, sourceRelay);
52
+ *
53
+ * return cleanup; // Only return cleanup for the additional effect
54
+ * });
55
+ * ```
56
+ */
57
+ export declare function forwardRelay<T>(state: RelayState<T>, sourceRelay: DiscriminatedReactivePromise<T>): void;
26
58
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAW1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAwB3C;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ1E,OAAO,EAAiB,UAAU,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAwB3C;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,IAAI,CA8BxG"}
package/dist/esm/utils.js CHANGED
@@ -50,4 +50,66 @@ export function watchOnce(fn) {
50
50
  }
51
51
  }
52
52
  export { setReactivePromise } from './internals/async.js';
53
+ /**
54
+ * Forwards state from a source relay to the target relay's state.
55
+ * This enables composition patterns where relays can add side effects
56
+ * while transparently forwarding state from another relay.
57
+ *
58
+ * The forwarding is automatically tracked through the signal graph.
59
+ * When the source relay updates, the target relay will re-run its
60
+ * activation function, and forwardRelay will forward the new state.
61
+ * No cleanup is needed - dependencies are managed automatically.
62
+ *
63
+ * @param state - The target relay's state object
64
+ * @param sourceRelay - The source relay to forward state from
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const sourceRelay = relay(state => {
69
+ * // ... source relay logic
70
+ * });
71
+ *
72
+ * const forwardedRelay = relay(state => {
73
+ * // Add additional side effect
74
+ * const cleanup = setupSomeEffect();
75
+ *
76
+ * // Forward state from source relay (automatically tracked and cleaned up)
77
+ * forwardRelay(state, sourceRelay);
78
+ *
79
+ * return cleanup; // Only return cleanup for the additional effect
80
+ * });
81
+ * ```
82
+ */
83
+ export function forwardRelay(state, sourceRelay) {
84
+ // Verify that sourceRelay is actually a ReactivePromiseImpl
85
+ if (!isReactivePromise(sourceRelay)) {
86
+ throw new Error('forwardRelay: sourceRelay must be a ReactivePromise');
87
+ }
88
+ // Read from source relay to establish dependency and forward state
89
+ // When sourceRelay updates, this relay's activation function will be called again,
90
+ // and forwardRelay will be called again, forwarding the new state
91
+ if (sourceRelay.isPending) {
92
+ // For pending state, try to forward the promise if available
93
+ // Accessing isPending establishes the dependency
94
+ const source = sourceRelay;
95
+ const promise = source['_promise'];
96
+ if (promise) {
97
+ state.setPromise(promise);
98
+ }
99
+ }
100
+ else if (sourceRelay.isRejected) {
101
+ // Accessing error establishes dependency and forwards it
102
+ const error = sourceRelay.error;
103
+ if (error !== undefined) {
104
+ state.setError(error);
105
+ }
106
+ }
107
+ else if (sourceRelay.isResolved && sourceRelay.isReady) {
108
+ // Accessing value establishes dependency and forwards it
109
+ const value = sourceRelay.value;
110
+ if (value !== undefined) {
111
+ state.value = value;
112
+ }
113
+ }
114
+ }
53
115
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAmB,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,SAAS,CAAI,EAAW;IACtC,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,CAAiC,CAAC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,WAAW,CAAC,MAAM,CAAC,CAAC;QAEpB,yCAAyC;QACzC,IAAI,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAE/B,IAAI,iBAAiB,CAAC,MAAgB,CAAC,IAAI,SAAS,CAAC,MAAgB,CAAC,EAAE,CAAC;YACvE,MAAM,GAAI,MAAqB,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC3C,aAAa,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC,CAAqB,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAY,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAuB,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,SAAS,CAAI,EAAW;IACtC,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,CAAiC,CAAC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,WAAW,CAAC,MAAM,CAAC,CAAC;QAEpB,yCAAyC;QACzC,IAAI,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAE/B,IAAI,iBAAiB,CAAC,MAAgB,CAAC,IAAI,SAAS,CAAC,MAAgB,CAAC,EAAE,CAAC;YACvE,MAAM,GAAI,MAAqB,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC3C,aAAa,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC,CAAqB,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,YAAY,CAAI,KAAoB,EAAE,WAA4C;IAChG,4DAA4D;IAC5D,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,mEAAmE;IACnE,mFAAmF;IACnF,kEAAkE;IAClE,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1B,6DAA6D;QAC7D,iDAAiD;QACjD,MAAM,MAAM,GAAG,WAAqC,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAA2B,CAAC;QAC7D,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAClC,yDAAyD;QACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzD,yDAAyD;QACzD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalium",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",