@rlabs-inc/signals 1.0.0 → 1.1.0

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/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { signal, source, mutableSource, state, stateRaw } from './primitives/signal.js';
2
2
  export { derived, createDerived, disconnectDerived } from './primitives/derived.js';
3
3
  export { effect, createEffect, updateEffect, destroyEffect } from './primitives/effect.js';
4
+ export { bind, bindReadonly, isBinding, unwrap } from './primitives/bind.js';
4
5
  export { proxy, toRaw, isReactive } from './deep/proxy.js';
5
6
  export { batch, untrack, peek } from './reactivity/batching.js';
6
7
  export { flushSync, tick } from './reactivity/scheduling.js';
@@ -12,4 +13,5 @@ export { get, set, isDirty, setSignalStatus, markReactions, updateReaction, remo
12
13
  export { DERIVED, EFFECT, RENDER_EFFECT, ROOT_EFFECT, BRANCH_EFFECT, USER_EFFECT, BLOCK_EFFECT, CLEAN, DIRTY, MAYBE_DIRTY, REACTION_IS_UPDATING, DESTROYED, INERT, EFFECT_RAN, EFFECT_PRESERVED, UNOWNED, DISCONNECTED, UNINITIALIZED, STALE_REACTION, STATE_SYMBOL, REACTIVE_MARKER, } from './core/constants.js';
13
14
  export { activeReaction, activeEffect, untracking, writeVersion, readVersion, batchDepth, setActiveReaction, setActiveEffect, setUntracking, incrementWriteVersion, incrementReadVersion, incrementBatchDepth, decrementBatchDepth, getReadVersion, getWriteVersion, getBatchDepth, } from './core/globals.js';
14
15
  export type { Signal, Source, Reaction, Derived, Effect, Value, ReadableSignal, WritableSignal, DerivedSignal, DisposeFn, CleanupFn, EffectFn, Equals, Uninitialized, } from './core/types.js';
16
+ export type { Binding, ReadonlyBinding } from './primitives/bind.js';
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACnF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAM1F,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAM1D,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAM5D,OAAO,EACL,MAAM,EACN,UAAU,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,0BAA0B,CAAA;AAMjC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAMpD,OAAO,EACL,GAAG,EACH,GAAG,EACH,OAAO,EACP,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA;AAMjC,OAAO,EAEL,OAAO,EACP,MAAM,EACN,aAAa,EACb,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EAGZ,KAAK,EACL,KAAK,EACL,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,KAAK,EACL,UAAU,EACV,gBAAgB,EAGhB,OAAO,EACP,YAAY,EAGZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EAGV,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EAGnB,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAA;AAM1B,YAAY,EAEV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,KAAK,EAGL,cAAc,EACd,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,QAAQ,EAGR,MAAM,EACN,aAAa,GACd,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACnF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC1F,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAM5E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAM1D,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAM5D,OAAO,EACL,MAAM,EACN,UAAU,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,0BAA0B,CAAA;AAMjC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAMpD,OAAO,EACL,GAAG,EACH,GAAG,EACH,OAAO,EACP,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,0BAA0B,CAAA;AAMjC,OAAO,EAEL,OAAO,EACP,MAAM,EACN,aAAa,EACb,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EAGZ,KAAK,EACL,KAAK,EACL,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,KAAK,EACL,UAAU,EACV,gBAAgB,EAGhB,OAAO,EACP,YAAY,EAGZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EAGV,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EAGnB,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAA;AAM1B,YAAY,EAEV,MAAM,EACN,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,EACN,KAAK,EAGL,cAAc,EACd,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,QAAQ,EAGR,MAAM,EACN,aAAa,GACd,MAAM,iBAAiB,CAAA;AAExB,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ __export(exports_src, {
32
32
  writeVersion: () => writeVersion,
33
33
  updateReaction: () => updateReaction,
34
34
  updateEffect: () => updateEffect,
35
+ unwrap: () => unwrap,
35
36
  untracking: () => untracking,
36
37
  untrack: () => untrack,
37
38
  toRaw: () => toRaw,
@@ -57,6 +58,7 @@ __export(exports_src, {
57
58
  markReactions: () => markReactions,
58
59
  isReactive: () => isReactive,
59
60
  isDirty: () => isDirty,
61
+ isBinding: () => isBinding,
60
62
  incrementWriteVersion: () => incrementWriteVersion,
61
63
  incrementReadVersion: () => incrementReadVersion,
62
64
  incrementBatchDepth: () => incrementBatchDepth,
@@ -74,6 +76,8 @@ __export(exports_src, {
74
76
  createEquals: () => createEquals,
75
77
  createEffect: () => createEffect,
76
78
  createDerived: () => createDerived,
79
+ bindReadonly: () => bindReadonly,
80
+ bind: () => bind,
77
81
  batchDepth: () => batchDepth,
78
82
  batch: () => batch,
79
83
  alwaysEquals: () => alwaysEquals,
@@ -957,6 +961,37 @@ effect.root = function effectRoot(fn) {
957
961
  effect.tracking = function effectTracking() {
958
962
  return activeEffect !== null;
959
963
  };
964
+ // src/primitives/bind.ts
965
+ var BINDING_SYMBOL = Symbol("binding");
966
+ function isBinding(value) {
967
+ return value !== null && typeof value === "object" && BINDING_SYMBOL in value;
968
+ }
969
+ function bind(source2) {
970
+ const binding = {
971
+ [BINDING_SYMBOL]: true,
972
+ get value() {
973
+ return source2.value;
974
+ },
975
+ set value(v) {
976
+ source2.value = v;
977
+ }
978
+ };
979
+ return binding;
980
+ }
981
+ function bindReadonly(source2) {
982
+ return {
983
+ [BINDING_SYMBOL]: true,
984
+ get value() {
985
+ return source2.value;
986
+ }
987
+ };
988
+ }
989
+ function unwrap(value) {
990
+ if (isBinding(value)) {
991
+ return value.value;
992
+ }
993
+ return value;
994
+ }
960
995
  // src/reactivity/batching.ts
961
996
  function batch(fn) {
962
997
  incrementBatchDepth();
package/dist/index.mjs CHANGED
@@ -849,6 +849,37 @@ effect.root = function effectRoot(fn) {
849
849
  effect.tracking = function effectTracking() {
850
850
  return activeEffect !== null;
851
851
  };
852
+ // src/primitives/bind.ts
853
+ var BINDING_SYMBOL = Symbol("binding");
854
+ function isBinding(value) {
855
+ return value !== null && typeof value === "object" && BINDING_SYMBOL in value;
856
+ }
857
+ function bind(source2) {
858
+ const binding = {
859
+ [BINDING_SYMBOL]: true,
860
+ get value() {
861
+ return source2.value;
862
+ },
863
+ set value(v) {
864
+ source2.value = v;
865
+ }
866
+ };
867
+ return binding;
868
+ }
869
+ function bindReadonly(source2) {
870
+ return {
871
+ [BINDING_SYMBOL]: true,
872
+ get value() {
873
+ return source2.value;
874
+ }
875
+ };
876
+ }
877
+ function unwrap(value) {
878
+ if (isBinding(value)) {
879
+ return value.value;
880
+ }
881
+ return value;
882
+ }
852
883
  // src/reactivity/batching.ts
853
884
  function batch(fn) {
854
885
  incrementBatchDepth();
@@ -1330,6 +1361,7 @@ export {
1330
1361
  writeVersion,
1331
1362
  updateReaction,
1332
1363
  updateEffect,
1364
+ unwrap,
1333
1365
  untracking,
1334
1366
  untrack,
1335
1367
  toRaw,
@@ -1355,6 +1387,7 @@ export {
1355
1387
  markReactions,
1356
1388
  isReactive,
1357
1389
  isDirty,
1390
+ isBinding,
1358
1391
  incrementWriteVersion,
1359
1392
  incrementReadVersion,
1360
1393
  incrementBatchDepth,
@@ -1372,6 +1405,8 @@ export {
1372
1405
  createEquals,
1373
1406
  createEffect,
1374
1407
  createDerived,
1408
+ bindReadonly,
1409
+ bind,
1375
1410
  batchDepth,
1376
1411
  batch,
1377
1412
  alwaysEquals,
@@ -0,0 +1,95 @@
1
+ import type { WritableSignal, ReadableSignal } from '../core/types.js';
2
+ /**
3
+ * A writable binding that forwards reads and writes to a source.
4
+ * Reading creates dependency on source, writing triggers source's reactions.
5
+ */
6
+ export interface Binding<T> {
7
+ get value(): T;
8
+ set value(v: T);
9
+ }
10
+ /**
11
+ * A read-only binding that forwards reads to a source.
12
+ * Reading creates dependency on source, writing throws an error.
13
+ */
14
+ export interface ReadonlyBinding<T> {
15
+ readonly value: T;
16
+ }
17
+ /**
18
+ * Check if a value is a binding created by bind()
19
+ */
20
+ export declare function isBinding(value: unknown): value is Binding<unknown>;
21
+ /**
22
+ * Create a reactive binding to a signal or another binding.
23
+ *
24
+ * A binding is a "reactive pointer" - it forwards reads and writes to the source.
25
+ * This enables connecting user's reactive state to internal component state.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const source = signal(0)
30
+ * const binding = bind(source)
31
+ *
32
+ * // Reading through binding reads from source (creates dependency)
33
+ * console.log(binding.value) // → 0
34
+ *
35
+ * // Writing through binding writes to source (triggers reactivity)
36
+ * binding.value = 42
37
+ * console.log(source.value) // → 42
38
+ * ```
39
+ *
40
+ * @example Two-way binding for inputs
41
+ * ```ts
42
+ * const username = signal('')
43
+ * const inputBinding = bind(username)
44
+ *
45
+ * // When user types:
46
+ * inputBinding.value = 'alice' // Updates username signal!
47
+ * ```
48
+ *
49
+ * @example Chaining bindings
50
+ * ```ts
51
+ * const source = signal(0)
52
+ * const b1 = bind(source)
53
+ * const b2 = bind(b1) // Points to same source
54
+ *
55
+ * b2.value = 99
56
+ * console.log(source.value) // → 99
57
+ * ```
58
+ */
59
+ export declare function bind<T>(source: WritableSignal<T>): Binding<T>;
60
+ export declare function bind<T>(source: ReadableSignal<T>): ReadonlyBinding<T>;
61
+ export declare function bind<T>(source: Binding<T>): Binding<T>;
62
+ export declare function bind<T>(source: ReadonlyBinding<T>): ReadonlyBinding<T>;
63
+ /**
64
+ * Create an explicitly read-only binding.
65
+ * Attempting to write will throw an error at runtime.
66
+ *
67
+ * Use this when you want to ensure a binding is never written to,
68
+ * even if the source is writable.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * const source = signal(0)
73
+ * const readonly = bindReadonly(source)
74
+ *
75
+ * console.log(readonly.value) // → 0
76
+ * readonly.value = 42 // Throws: Cannot write to a read-only binding
77
+ * ```
78
+ */
79
+ export declare function bindReadonly<T>(source: ReadableSignal<T> | Binding<T>): ReadonlyBinding<T>;
80
+ /**
81
+ * Get the value from a binding or return the value directly if not a binding.
82
+ * Useful for reading values that may or may not be bound.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const arr: (string | Binding<string>)[] = [
87
+ * 'static',
88
+ * bind(signal('dynamic'))
89
+ * ]
90
+ *
91
+ * arr.map(unwrap) // → ['static', 'dynamic']
92
+ * ```
93
+ */
94
+ export declare function unwrap<T>(value: T | Binding<T> | ReadonlyBinding<T>): T;
95
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../src/primitives/bind.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAMtE;;;GAGG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,IAAI,KAAK,IAAI,CAAC,CAAA;IACd,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,EAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAQD;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAEnE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAC9D,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AACtE,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AACvD,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AA6BvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAQ1F;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAKvE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rlabs-inc/signals",
3
- "version": "1.0.0",
4
- "description": "Production-grade fine-grained reactivity for TypeScript. A complete standalone mirror of Svelte 5's reactivity system - signals, effects, derived values, deep reactivity, and reactive collections.",
3
+ "version": "1.1.0",
4
+ "description": "Production-grade fine-grained reactivity for TypeScript. A complete standalone mirror of Svelte 5's reactivity system - signals, effects, derived values, deep reactivity, reactive collections, and reactive bindings.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",