@fluixi/reactive 1.0.0-alpha.82 → 1.0.0-alpha.84

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 (169) hide show
  1. package/README.md +4 -0
  2. package/dist/cdn/reactive.cjs +2673 -1
  3. package/dist/cdn/reactive.global.js +2 -1
  4. package/dist/cdn/reactive.mjs +2657 -1
  5. package/dist/cdn/signal.cjs +299 -1
  6. package/dist/cdn/signal.d.ts +1 -1
  7. package/dist/cdn/signal.global.js +2 -1
  8. package/dist/cdn/signal.js +1 -1
  9. package/dist/cdn/signal.mjs +276 -1
  10. package/dist/index.cjs +2673 -1
  11. package/dist/index.mjs +2657 -1
  12. package/dist/lib/index.cjs +2674 -1
  13. package/dist/lib/index.js +1 -1
  14. package/dist/lib/index.mjs +2659 -1
  15. package/dist/lib/observable/index.cjs +386 -1
  16. package/dist/lib/observable/index.mjs +364 -1
  17. package/dist/lib/observable/observable.cjs +384 -1
  18. package/dist/lib/observable/observable.d.ts +0 -137
  19. package/dist/lib/observable/observable.d.ts.map +1 -1
  20. package/dist/lib/observable/observable.js +0 -71
  21. package/dist/lib/observable/observable.mjs +361 -1
  22. package/dist/lib/observable/subscription.cjs +180 -1
  23. package/dist/lib/observable/subscription.d.ts +0 -12
  24. package/dist/lib/observable/subscription.d.ts.map +1 -1
  25. package/dist/lib/observable/subscription.js +0 -12
  26. package/dist/lib/observable/subscription.mjs +157 -1
  27. package/dist/lib/observable/types.cjs +18 -1
  28. package/dist/lib/observable/types.d.ts.map +1 -1
  29. package/dist/lib/predicates.cjs +44 -1
  30. package/dist/lib/predicates.d.ts +2 -2
  31. package/dist/lib/predicates.js +2 -2
  32. package/dist/lib/predicates.mjs +23 -1
  33. package/dist/lib/signal/api.cjs +571 -1
  34. package/dist/lib/signal/api.d.ts +211 -1
  35. package/dist/lib/signal/api.d.ts.map +1 -1
  36. package/dist/lib/signal/api.js +207 -12
  37. package/dist/lib/signal/api.mjs +548 -1
  38. package/dist/lib/signal/cached-resource.cjs +672 -1
  39. package/dist/lib/signal/cached-resource.d.ts +28 -16
  40. package/dist/lib/signal/cached-resource.d.ts.map +1 -1
  41. package/dist/lib/signal/cached-resource.js +35 -29
  42. package/dist/lib/signal/cached-resource.mjs +650 -1
  43. package/dist/lib/signal/graph/children.cjs +325 -1
  44. package/dist/lib/signal/graph/children.js +1 -1
  45. package/dist/lib/signal/graph/children.mjs +302 -1
  46. package/dist/lib/signal/graph/compat.cjs +578 -1
  47. package/dist/lib/signal/graph/compat.d.ts +13 -13
  48. package/dist/lib/signal/graph/compat.d.ts.map +1 -1
  49. package/dist/lib/signal/graph/compat.js +51 -32
  50. package/dist/lib/signal/graph/compat.mjs +556 -1
  51. package/dist/lib/signal/graph/core.cjs +295 -1
  52. package/dist/lib/signal/graph/core.d.ts +28 -24
  53. package/dist/lib/signal/graph/core.d.ts.map +1 -1
  54. package/dist/lib/signal/graph/core.js +45 -31
  55. package/dist/lib/signal/graph/core.mjs +273 -1
  56. package/dist/lib/signal/graph/debounced.cjs +668 -1
  57. package/dist/lib/signal/graph/debounced.d.ts +5 -5
  58. package/dist/lib/signal/graph/debounced.d.ts.map +1 -1
  59. package/dist/lib/signal/graph/debounced.js +5 -5
  60. package/dist/lib/signal/graph/debounced.mjs +645 -1
  61. package/dist/lib/signal/graph/derived.cjs +496 -1
  62. package/dist/lib/signal/graph/derived.d.ts +1 -1
  63. package/dist/lib/signal/graph/derived.js +1 -1
  64. package/dist/lib/signal/graph/derived.mjs +473 -1
  65. package/dist/lib/signal/graph/detect.cjs +66 -1
  66. package/dist/lib/signal/graph/detect.mjs +45 -1
  67. package/dist/lib/signal/graph/error-boundary.cjs +301 -1
  68. package/dist/lib/signal/graph/error-boundary.js +3 -3
  69. package/dist/lib/signal/graph/error-boundary.mjs +278 -1
  70. package/dist/lib/signal/graph/index.cjs +305 -1
  71. package/dist/lib/signal/graph/index.d.ts +7 -6
  72. package/dist/lib/signal/graph/index.d.ts.map +1 -1
  73. package/dist/lib/signal/graph/index.js +7 -6
  74. package/dist/lib/signal/graph/index.mjs +283 -1
  75. package/dist/lib/signal/graph/observe.cjs +163 -0
  76. package/dist/lib/signal/graph/observe.d.ts +141 -0
  77. package/dist/lib/signal/graph/observe.d.ts.map +1 -0
  78. package/dist/lib/signal/graph/observe.js +149 -0
  79. package/dist/lib/signal/graph/observe.mjs +140 -0
  80. package/dist/lib/signal/graph/resource.cjs +620 -1
  81. package/dist/lib/signal/graph/resource.d.ts +1 -1
  82. package/dist/lib/signal/graph/resource.js +7 -8
  83. package/dist/lib/signal/graph/resource.mjs +597 -1
  84. package/dist/lib/signal/graph/runtime.cjs +501 -1
  85. package/dist/lib/signal/graph/runtime.d.ts +9 -9
  86. package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
  87. package/dist/lib/signal/graph/runtime.js +56 -37
  88. package/dist/lib/signal/graph/runtime.mjs +478 -1
  89. package/dist/lib/signal/graph/signal-next.cjs +1208 -1
  90. package/dist/lib/signal/graph/signal-next.d.ts +5 -5
  91. package/dist/lib/signal/graph/signal-next.d.ts.map +1 -1
  92. package/dist/lib/signal/graph/signal-next.js +14 -12
  93. package/dist/lib/signal/graph/signal-next.mjs +1186 -1
  94. package/dist/lib/signal/graph/ssr-hooks.cjs +60 -1
  95. package/dist/lib/signal/graph/ssr-hooks.d.ts +6 -7
  96. package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -1
  97. package/dist/lib/signal/graph/ssr-hooks.js +6 -7
  98. package/dist/lib/signal/graph/ssr-hooks.mjs +39 -1
  99. package/dist/lib/signal/graph/state.cjs +72 -1
  100. package/dist/lib/signal/graph/state.d.ts +43 -10
  101. package/dist/lib/signal/graph/state.d.ts.map +1 -1
  102. package/dist/lib/signal/graph/state.js +83 -21
  103. package/dist/lib/signal/graph/state.mjs +49 -1
  104. package/dist/lib/signal/graph/suspense.cjs +301 -1
  105. package/dist/lib/signal/graph/suspense.js +4 -4
  106. package/dist/lib/signal/graph/suspense.mjs +278 -1
  107. package/dist/lib/signal/index-legacy.cjs +2540 -1
  108. package/dist/lib/signal/index-legacy.d.ts +1 -1
  109. package/dist/lib/signal/index-legacy.js +1 -1
  110. package/dist/lib/signal/index-legacy.mjs +2518 -1
  111. package/dist/lib/signal/index.cjs +1275 -1
  112. package/dist/lib/signal/index.d.ts +5 -2
  113. package/dist/lib/signal/index.d.ts.map +1 -1
  114. package/dist/lib/signal/index.js +8 -3
  115. package/dist/lib/signal/index.mjs +1253 -1
  116. package/dist/lib/signal/list.cjs +549 -1
  117. package/dist/lib/signal/list.d.ts +5 -5
  118. package/dist/lib/signal/list.js +10 -10
  119. package/dist/lib/signal/list.mjs +526 -1
  120. package/dist/lib/signal/resource-api.cjs +626 -1
  121. package/dist/lib/signal/resource-api.d.ts +5 -5
  122. package/dist/lib/signal/resource-api.js +5 -5
  123. package/dist/lib/signal/resource-api.mjs +603 -1
  124. package/dist/lib/signal/signal.cjs +2023 -1
  125. package/dist/lib/signal/signal.d.ts +4 -4
  126. package/dist/lib/signal/signal.d.ts.map +1 -1
  127. package/dist/lib/signal/signal.js +22 -23
  128. package/dist/lib/signal/signal.mjs +2000 -1
  129. package/dist/lib/signal/types.cjs +38 -1
  130. package/dist/lib/signal/types.d.ts.map +1 -1
  131. package/dist/lib/signal/types.js +2 -2
  132. package/dist/lib/signal/types.mjs +17 -1
  133. package/dist/lib/signal/utilities.cjs +1012 -1
  134. package/dist/lib/signal/utilities.d.ts +0 -108
  135. package/dist/lib/signal/utilities.d.ts.map +1 -1
  136. package/dist/lib/signal/utilities.js +0 -158
  137. package/dist/lib/signal/utilities.mjs +990 -1
  138. package/dist/lib/store/api.cjs +612 -1
  139. package/dist/lib/store/api.d.ts +33 -0
  140. package/dist/lib/store/api.d.ts.map +1 -1
  141. package/dist/lib/store/api.js +41 -8
  142. package/dist/lib/store/api.mjs +596 -1
  143. package/dist/lib/store/index.cjs +691 -1
  144. package/dist/lib/store/index.js +1 -1
  145. package/dist/lib/store/index.mjs +676 -1
  146. package/dist/lib/store/setter.types.cjs +18 -1
  147. package/dist/lib/store/setter.types.d.ts +43 -3
  148. package/dist/lib/store/setter.types.d.ts.map +1 -1
  149. package/dist/lib/store/store.cjs +658 -1
  150. package/dist/lib/store/store.d.ts +72 -0
  151. package/dist/lib/store/store.d.ts.map +1 -1
  152. package/dist/lib/store/store.js +294 -11
  153. package/dist/lib/store/store.mjs +644 -1
  154. package/dist/lib/store/types.cjs +18 -1
  155. package/dist/lib/store/types.d.ts +1 -1
  156. package/dist/lib/store/types.d.ts.map +1 -1
  157. package/dist/lib/store/utils.cjs +43 -1
  158. package/dist/lib/store/utils.d.ts +1 -1
  159. package/dist/lib/store/utils.js +1 -1
  160. package/dist/lib/store/utils.mjs +22 -1
  161. package/dist/lib/subject.cjs +450 -1
  162. package/dist/lib/subject.js +3 -91
  163. package/dist/lib/subject.mjs +427 -1
  164. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  165. package/dist/version.generated.cjs +27 -1
  166. package/dist/version.generated.d.ts +1 -1
  167. package/dist/version.generated.js +2 -2
  168. package/dist/version.generated.mjs +7 -1
  169. package/package.json +5 -4
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/signal/graph/observe.ts
21
+ var observe_exports = {};
22
+ __export(observe_exports, {
23
+ enterReactiveRun: () => enterReactiveRun,
24
+ exitReactiveRun: () => exitReactiveRun,
25
+ isObserved: () => isObserved,
26
+ observeReactiveNodes: () => observeReactiveNodes,
27
+ reportReactiveBinding: () => reportReactiveBinding,
28
+ reportReactiveContext: () => reportReactiveContext,
29
+ reportReactiveContextCreated: () => reportReactiveContextCreated,
30
+ reportReactiveDirective: () => reportReactiveDirective,
31
+ reportReactiveDispose: () => reportReactiveDispose,
32
+ reportReactiveMove: () => reportReactiveMove,
33
+ reportReactiveNode: () => reportReactiveNode,
34
+ reportReactiveProps: () => reportReactiveProps,
35
+ reportReactiveRun: () => reportReactiveRun,
36
+ reportReactiveWrite: () => reportReactiveWrite,
37
+ withReactiveOrigin: () => withReactiveOrigin
38
+ });
39
+ module.exports = __toCommonJS(observe_exports);
40
+
41
+ // src/version.generated.ts
42
+ var VERSION = "1.0.0-alpha.84";
43
+
44
+ // src/lib/signal/graph/state.ts
45
+ var MAJOR = VERSION.split(".")[0];
46
+ var KEY = `__fluixi_signal_state_v${MAJOR}__`;
47
+ var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
48
+ var defaultSchedule = (run) => {
49
+ if (typeof queueMicrotask === "function") queueMicrotask(run);
50
+ else void Promise.resolve().then(run);
51
+ };
52
+ function defaults() {
53
+ return {
54
+ consumer: null,
55
+ untracked: false,
56
+ owner: null,
57
+ queue: [],
58
+ scheduled: false,
59
+ flushing: false,
60
+ batchDepth: 0,
61
+ hostSchedule: defaultSchedule,
62
+ onSuspend: null,
63
+ onError: null,
64
+ observer: null
65
+ };
66
+ }
67
+ var realm = globalThis;
68
+ function backfillState(existing) {
69
+ const fresh = defaults();
70
+ const target = existing;
71
+ for (const field of Object.keys(fresh)) {
72
+ if (!(field in existing)) target[field] = fresh[field];
73
+ }
74
+ return existing;
75
+ }
76
+ function claim() {
77
+ const existing = realm[KEY];
78
+ return existing ? backfillState(existing) : realm[KEY] = defaults();
79
+ }
80
+ var G = claim();
81
+ (realm[VERSIONS_KEY] ??= []).push(VERSION);
82
+
83
+ // src/lib/signal/graph/observe.ts
84
+ function observeReactiveNodes(next) {
85
+ G.observer = next;
86
+ return () => {
87
+ if (G.observer === next) G.observer = null;
88
+ };
89
+ }
90
+ var running = [];
91
+ var origin;
92
+ function withReactiveOrigin(owner, fn) {
93
+ if (!G.observer) return fn();
94
+ const previous = origin;
95
+ origin = owner;
96
+ try {
97
+ return fn();
98
+ } finally {
99
+ origin = previous;
100
+ }
101
+ }
102
+ function reportReactiveNode(report) {
103
+ const observer = G.observer;
104
+ if (observer) {
105
+ observer.created(
106
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
107
+ );
108
+ }
109
+ }
110
+ function enterReactiveRun(node) {
111
+ if (!G.observer) return false;
112
+ running.push(node);
113
+ return true;
114
+ }
115
+ function exitReactiveRun() {
116
+ running.pop();
117
+ }
118
+ function reportReactiveRun(node) {
119
+ G.observer?.ran?.(node);
120
+ }
121
+ function reportReactiveWrite(node, by) {
122
+ G.observer?.wrote?.(node, by);
123
+ }
124
+ function reportReactiveBinding(target, kind, name, accessor) {
125
+ const observer = G.observer;
126
+ if (!observer?.bound || !running.length) return;
127
+ observer.bound(running[running.length - 1], target, kind, name, accessor);
128
+ }
129
+ function reportReactiveProps(props) {
130
+ const observer = G.observer;
131
+ if (!observer?.props || !running.length || !props) return;
132
+ observer.props(running[running.length - 1], props);
133
+ }
134
+ function reportReactiveDirective(target, kind, name, accessor) {
135
+ const observer = G.observer;
136
+ if (!observer?.directive || !running.length) return;
137
+ observer.directive(running[running.length - 1], target, kind, name, accessor);
138
+ }
139
+ function reportReactiveContextCreated(id) {
140
+ G.observer?.contextCreated?.(id);
141
+ }
142
+ function reportReactiveContext(id, kind, value) {
143
+ const observer = G.observer;
144
+ if (!observer?.context || !running.length) return;
145
+ observer.context(running[running.length - 1], id, kind, value);
146
+ }
147
+ function reportReactiveMove(node, origin2, name) {
148
+ G.observer?.moved?.(node, origin2, name);
149
+ }
150
+ function reportReactiveDispose(node) {
151
+ G.observer?.disposed?.(node);
152
+ }
153
+ var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
154
+ var hook = globalThis[HOOK];
155
+ if (typeof hook?.inject === "function") {
156
+ try {
157
+ hook.inject({ observeReactiveNodes, version: VERSION });
158
+ } catch {
159
+ }
160
+ }
161
+ function isObserved() {
162
+ return G.observer != null;
163
+ }
@@ -0,0 +1,141 @@
1
+ export type ReactiveNodeKind = 'signal' | 'memo' | 'effect' | 'store' | 'resource';
2
+ export interface ReactiveNodeReport {
3
+ kind: ReactiveNodeKind;
4
+ /** The core node. Edges hang off this, and it is the identity later reports use. */
5
+ node: unknown;
6
+ /** What the caller was handed, when that is a different object from the node. */
7
+ handle?: unknown;
8
+ /** The name the call site gave, if it gave one. */
9
+ name?: string;
10
+ /**
11
+ * How to write it, for a signal. A watcher setting the value through this goes through
12
+ * the same path the application does, writing the node directly marks its readers dirty
13
+ * without ever flushing them, so the page keeps whatever it last rendered.
14
+ */
15
+ set?: (value: unknown) => void;
16
+ /**
17
+ * The node this one was built for. A store creates a signal per key, lazily, wherever it
18
+ * is first read, the useful location is the store's, not the reader's.
19
+ */
20
+ origin?: unknown;
21
+ /**
22
+ * The node is the framework's own plumbing, a render effect, one per dom binding. A graph
23
+ * does not show these, but it needs to know they exist: a row added to a list is created
24
+ * inside one, and without it the row has no ancestor it can be attached to.
25
+ */
26
+ internal?: boolean;
27
+ /**
28
+ * The computations running when this node was made, outermost first. A component's wrapper
29
+ * memo reads nothing itself, so what it created is the only thing tying it to the graph
30
+ * and the whole chain is given because the nearest one is often a render effect, which no
31
+ * graph shows.
32
+ *
33
+ * Live and reused: read it during the call, do not keep it.
34
+ */
35
+ parents?: readonly unknown[];
36
+ }
37
+ export interface ReactiveObserver {
38
+ created(report: ReactiveNodeReport): void;
39
+ /** A computation recomputed. Effects have no value to diff, so this is their only signal. */
40
+ ran?(node: unknown): void;
41
+ /** An effect was disposed. Memos and signals go with their owner and are not reported. */
42
+ disposed?(node: unknown): void;
43
+ /**
44
+ * A signal was written, and by which computation, nothing, when the write came from an
45
+ * event handler, which is where most of them come from.
46
+ */
47
+ wrote?(node: unknown, by: unknown): void;
48
+ /**
49
+ * A node now belongs somewhere else, and is called something else.
50
+ *
51
+ * A store write replaces the object that held a value: `set({ items: [...items, one] })`
52
+ * builds a new array, and the signals underneath it are the same signals in a new place.
53
+ * Without this they keep pointing at a node that no longer exists.
54
+ */
55
+ moved?(node: unknown, origin: unknown, name?: string): void;
56
+ /**
57
+ * A computation writes to this piece of the document. Only the dom layer knows a reader is
58
+ * the text of an `<li>` and not a `class`, and only as it wires the binding up.
59
+ *
60
+ * `node` is the render effect doing it. `accessor` is the function it reads, which the
61
+ * compiler may have stamped with the hole's position.
62
+ */
63
+ bound?(node: unknown, target: unknown, kind: string, name?: string, accessor?: unknown): void;
64
+ /**
65
+ * The props a component was handed.
66
+ *
67
+ * `node` is the computation the component was created inside, which is the node a watcher
68
+ * draws it as. The object is kept rather than read: every prop is a getter over whatever
69
+ * the caller passed, so reading one here would subscribe the wrong computation to it.
70
+ */
71
+ props?(node: unknown, props: unknown): void;
72
+ /**
73
+ * A directive applied to an element: `use:`, `class:`, `style:`, `bind:`.
74
+ *
75
+ * `bound` says a value writes to a class or a style but not which key, so two `class:`
76
+ * directives on one element both report as `class`. This carries the key too.
77
+ */
78
+ directive?(node: unknown, target: unknown, kind: string, name: string, accessor?: unknown): void;
79
+ /**
80
+ * A context provided or read.
81
+ *
82
+ * Nothing else in the graph records it: a provider stamps a value on the owner chain and a
83
+ * reader walks up looking for it, so neither is a dependency and no edge is ever made.
84
+ */
85
+ context?(node: unknown, id: symbol, kind: 'provide' | 'read', value?: unknown): void;
86
+ /**
87
+ * A context was created. Separate from providing it, because a context is usually made at
88
+ * module scope with nothing running, and the line it was written on is the one worth
89
+ * showing. The watcher reads its own stack for that.
90
+ */
91
+ contextCreated?(id: symbol): void;
92
+ }
93
+ /**
94
+ * Watch the graph. Returns a function that stops watching.
95
+ *
96
+ * One observer at a time, the last to register wins. Two tools watching one page at once is
97
+ * not a case worth carrying state for.
98
+ */
99
+ export declare function observeReactiveNodes(next: ReactiveObserver): () => void;
100
+ /** Attribute everything `fn` creates to `owner`. Free when nobody is watching. */
101
+ export declare function withReactiveOrigin<T>(owner: unknown, fn: () => T): T;
102
+ /** Called by the primitives. Not part of the public surface. */
103
+ export declare function reportReactiveNode(report: ReactiveNodeReport): void;
104
+ /** Called around a recompute, so a node can say what it was created inside. */
105
+ export declare function enterReactiveRun(node: unknown): boolean;
106
+ export declare function exitReactiveRun(): void;
107
+ /** Called from the recompute path, so it stays a property read when nobody is watching. */
108
+ export declare function reportReactiveRun(node: unknown): void;
109
+ /** Called from the write path, so it stays a property read when nobody is watching. */
110
+ export declare function reportReactiveWrite(node: unknown, by: unknown): void;
111
+ /**
112
+ * The node is whatever is running: a binding is set up inside its own render effect. Nothing
113
+ * is pushed when no one is watching, so this stays a property read on the hot path.
114
+ */
115
+ export declare function reportReactiveBinding(target: unknown, kind: string, name?: string, accessor?: unknown): void;
116
+ /**
117
+ * A component's props, reported where it is created so the running computation is the one
118
+ * the props belong to. Nothing is read: the caller keeps the object and reads it untracked
119
+ * when someone asks.
120
+ */
121
+ export declare function reportReactiveProps(props: unknown): void;
122
+ /**
123
+ * As `reportReactiveBinding`: the node is whatever is running, since a directive is applied
124
+ * while its element is being built. A property read when nobody is watching.
125
+ */
126
+ export declare function reportReactiveDirective(target: unknown, kind: string, name: string, accessor?: unknown): void;
127
+ /** Called where the context is made, so a watcher can take the line from its own stack. */
128
+ export declare function reportReactiveContextCreated(id: symbol): void;
129
+ /** As the others: the node is whatever is running, and nothing happens without a watcher. */
130
+ export declare function reportReactiveContext(id: symbol, kind: 'provide' | 'read', value?: unknown): void;
131
+ export declare function reportReactiveMove(node: unknown, origin: unknown, name?: string): void;
132
+ export declare function reportReactiveDispose(node: unknown): void;
133
+ export interface DevtoolsHook {
134
+ inject?(runtime: {
135
+ observeReactiveNodes: typeof observeReactiveNodes;
136
+ version: string;
137
+ }): void;
138
+ }
139
+ /** Whether anything is watching, for a caller that would otherwise do work to report. */
140
+ export declare function isObserved(): boolean;
141
+ //# sourceMappingURL=observe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../../../src/lib/signal/graph/observe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * A place for a tool to watch the reactive graph from outside it.
3
+ *
4
+ * The runtime says a node exists, a computation re-ran, or an effect went away, and hands
5
+ * over the node itself. It does nothing else. Edges are already on the node, a source keeps
6
+ * its `observers`, a consumer keeps its `sources`, so a watcher reads the graph rather than
7
+ * reconstructing it, and nothing here wraps or replaces a primitive.
8
+ *
9
+ * Nothing is registered by default: an unwatched runtime pays one null check per node
10
+ * creation and per recompute.
11
+ *
12
+ * @fluixi/devtools is the intended caller. Nothing in the framework reads it back.
13
+ *
14
+ * The observer lives on the shared graph state rather than in a module `let`, so a bundle
15
+ * carrying two copies of this module still has one observer, the same reason G exists.
16
+ */
17
+ import { G } from './state.js';
18
+ import { VERSION } from '../../../version.generated.js';
19
+ /**
20
+ * Watch the graph. Returns a function that stops watching.
21
+ *
22
+ * One observer at a time, the last to register wins. Two tools watching one page at once is
23
+ * not a case worth carrying state for.
24
+ */
25
+ export function observeReactiveNodes(next) {
26
+ G.observer = next;
27
+ return () => {
28
+ if (G.observer === next)
29
+ G.observer = null;
30
+ };
31
+ }
32
+ /** What is running right now, outermost first. Empty unless something is watching. */
33
+ const running = [];
34
+ /** What the nodes created in here belong to. See ReactiveNodeReport.origin. */
35
+ let origin;
36
+ /** Attribute everything `fn` creates to `owner`. Free when nobody is watching. */
37
+ export function withReactiveOrigin(owner, fn) {
38
+ if (!G.observer)
39
+ return fn();
40
+ const previous = origin;
41
+ origin = owner;
42
+ try {
43
+ return fn();
44
+ }
45
+ finally {
46
+ origin = previous;
47
+ }
48
+ }
49
+ /** Called by the primitives. Not part of the public surface. */
50
+ export function reportReactiveNode(report) {
51
+ const observer = G.observer;
52
+ // Filled here rather than at each call site: the stack is already on hand, and a report
53
+ // costs nothing to build when nobody is watching.
54
+ if (observer) {
55
+ observer.created(report.parents === undefined ? { ...report, parents: running, origin: report.origin ?? origin } : report);
56
+ }
57
+ }
58
+ /** Called around a recompute, so a node can say what it was created inside. */
59
+ export function enterReactiveRun(node) {
60
+ if (!G.observer)
61
+ return false;
62
+ running.push(node);
63
+ return true;
64
+ }
65
+ export function exitReactiveRun() {
66
+ running.pop();
67
+ }
68
+ /** Called from the recompute path, so it stays a property read when nobody is watching. */
69
+ export function reportReactiveRun(node) {
70
+ G.observer?.ran?.(node);
71
+ }
72
+ /** Called from the write path, so it stays a property read when nobody is watching. */
73
+ export function reportReactiveWrite(node, by) {
74
+ G.observer?.wrote?.(node, by);
75
+ }
76
+ /**
77
+ * The node is whatever is running: a binding is set up inside its own render effect. Nothing
78
+ * is pushed when no one is watching, so this stays a property read on the hot path.
79
+ */
80
+ export function reportReactiveBinding(target, kind, name, accessor) {
81
+ const observer = G.observer;
82
+ if (!observer?.bound || !running.length)
83
+ return;
84
+ // The compiler may have stamped the accessor with the hole's line. A stack cannot say it:
85
+ // every binding in a template comes from the same generated expression.
86
+ observer.bound(running[running.length - 1], target, kind, name, accessor);
87
+ }
88
+ /**
89
+ * A component's props, reported where it is created so the running computation is the one
90
+ * the props belong to. Nothing is read: the caller keeps the object and reads it untracked
91
+ * when someone asks.
92
+ */
93
+ export function reportReactiveProps(props) {
94
+ const observer = G.observer;
95
+ if (!observer?.props || !running.length || !props)
96
+ return;
97
+ observer.props(running[running.length - 1], props);
98
+ }
99
+ /**
100
+ * As `reportReactiveBinding`: the node is whatever is running, since a directive is applied
101
+ * while its element is being built. A property read when nobody is watching.
102
+ */
103
+ export function reportReactiveDirective(target, kind, name, accessor) {
104
+ const observer = G.observer;
105
+ if (!observer?.directive || !running.length)
106
+ return;
107
+ observer.directive(running[running.length - 1], target, kind, name, accessor);
108
+ }
109
+ /** Called where the context is made, so a watcher can take the line from its own stack. */
110
+ export function reportReactiveContextCreated(id) {
111
+ G.observer?.contextCreated?.(id);
112
+ }
113
+ /** As the others: the node is whatever is running, and nothing happens without a watcher. */
114
+ export function reportReactiveContext(id, kind, value) {
115
+ const observer = G.observer;
116
+ if (!observer?.context || !running.length)
117
+ return;
118
+ observer.context(running[running.length - 1], id, kind, value);
119
+ }
120
+ export function reportReactiveMove(node, origin, name) {
121
+ G.observer?.moved?.(node, origin, name);
122
+ }
123
+ export function reportReactiveDispose(node) {
124
+ G.observer?.disposed?.(node);
125
+ }
126
+ /**
127
+ * Where a tool that cannot be imported finds the runtime.
128
+ *
129
+ * An extension has no way into an application's module graph, and an application should not
130
+ * have to import a debugger to be debuggable. So a tool sets this global before any of the
131
+ * app loads, and the runtime hands it the door on the way past.
132
+ *
133
+ * Set it too late and nothing happens, the runtime only offers once, when this module is
134
+ * first evaluated. A browser agent has to run at document_start for that reason.
135
+ */
136
+ const HOOK = '__FLUIXI_DEVTOOLS_HOOK__';
137
+ const hook = globalThis[HOOK];
138
+ if (typeof hook?.inject === 'function') {
139
+ try {
140
+ hook.inject({ observeReactiveNodes, version: VERSION });
141
+ }
142
+ catch {
143
+ // A broken tool is not the application's problem.
144
+ }
145
+ }
146
+ /** Whether anything is watching, for a caller that would otherwise do work to report. */
147
+ export function isObserved() {
148
+ return G.observer != null;
149
+ }
@@ -0,0 +1,140 @@
1
+ // src/version.generated.ts
2
+ var VERSION = "1.0.0-alpha.84";
3
+
4
+ // src/lib/signal/graph/state.ts
5
+ var MAJOR = VERSION.split(".")[0];
6
+ var KEY = `__fluixi_signal_state_v${MAJOR}__`;
7
+ var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
8
+ var defaultSchedule = (run) => {
9
+ if (typeof queueMicrotask === "function") queueMicrotask(run);
10
+ else void Promise.resolve().then(run);
11
+ };
12
+ function defaults() {
13
+ return {
14
+ consumer: null,
15
+ untracked: false,
16
+ owner: null,
17
+ queue: [],
18
+ scheduled: false,
19
+ flushing: false,
20
+ batchDepth: 0,
21
+ hostSchedule: defaultSchedule,
22
+ onSuspend: null,
23
+ onError: null,
24
+ observer: null
25
+ };
26
+ }
27
+ var realm = globalThis;
28
+ function backfillState(existing) {
29
+ const fresh = defaults();
30
+ const target = existing;
31
+ for (const field of Object.keys(fresh)) {
32
+ if (!(field in existing)) target[field] = fresh[field];
33
+ }
34
+ return existing;
35
+ }
36
+ function claim() {
37
+ const existing = realm[KEY];
38
+ return existing ? backfillState(existing) : realm[KEY] = defaults();
39
+ }
40
+ var G = claim();
41
+ (realm[VERSIONS_KEY] ??= []).push(VERSION);
42
+
43
+ // src/lib/signal/graph/observe.ts
44
+ function observeReactiveNodes(next) {
45
+ G.observer = next;
46
+ return () => {
47
+ if (G.observer === next) G.observer = null;
48
+ };
49
+ }
50
+ var running = [];
51
+ var origin;
52
+ function withReactiveOrigin(owner, fn) {
53
+ if (!G.observer) return fn();
54
+ const previous = origin;
55
+ origin = owner;
56
+ try {
57
+ return fn();
58
+ } finally {
59
+ origin = previous;
60
+ }
61
+ }
62
+ function reportReactiveNode(report) {
63
+ const observer = G.observer;
64
+ if (observer) {
65
+ observer.created(
66
+ report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
67
+ );
68
+ }
69
+ }
70
+ function enterReactiveRun(node) {
71
+ if (!G.observer) return false;
72
+ running.push(node);
73
+ return true;
74
+ }
75
+ function exitReactiveRun() {
76
+ running.pop();
77
+ }
78
+ function reportReactiveRun(node) {
79
+ G.observer?.ran?.(node);
80
+ }
81
+ function reportReactiveWrite(node, by) {
82
+ G.observer?.wrote?.(node, by);
83
+ }
84
+ function reportReactiveBinding(target, kind, name, accessor) {
85
+ const observer = G.observer;
86
+ if (!observer?.bound || !running.length) return;
87
+ observer.bound(running[running.length - 1], target, kind, name, accessor);
88
+ }
89
+ function reportReactiveProps(props) {
90
+ const observer = G.observer;
91
+ if (!observer?.props || !running.length || !props) return;
92
+ observer.props(running[running.length - 1], props);
93
+ }
94
+ function reportReactiveDirective(target, kind, name, accessor) {
95
+ const observer = G.observer;
96
+ if (!observer?.directive || !running.length) return;
97
+ observer.directive(running[running.length - 1], target, kind, name, accessor);
98
+ }
99
+ function reportReactiveContextCreated(id) {
100
+ G.observer?.contextCreated?.(id);
101
+ }
102
+ function reportReactiveContext(id, kind, value) {
103
+ const observer = G.observer;
104
+ if (!observer?.context || !running.length) return;
105
+ observer.context(running[running.length - 1], id, kind, value);
106
+ }
107
+ function reportReactiveMove(node, origin2, name) {
108
+ G.observer?.moved?.(node, origin2, name);
109
+ }
110
+ function reportReactiveDispose(node) {
111
+ G.observer?.disposed?.(node);
112
+ }
113
+ var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
114
+ var hook = globalThis[HOOK];
115
+ if (typeof hook?.inject === "function") {
116
+ try {
117
+ hook.inject({ observeReactiveNodes, version: VERSION });
118
+ } catch {
119
+ }
120
+ }
121
+ function isObserved() {
122
+ return G.observer != null;
123
+ }
124
+ export {
125
+ enterReactiveRun,
126
+ exitReactiveRun,
127
+ isObserved,
128
+ observeReactiveNodes,
129
+ reportReactiveBinding,
130
+ reportReactiveContext,
131
+ reportReactiveContextCreated,
132
+ reportReactiveDirective,
133
+ reportReactiveDispose,
134
+ reportReactiveMove,
135
+ reportReactiveNode,
136
+ reportReactiveProps,
137
+ reportReactiveRun,
138
+ reportReactiveWrite,
139
+ withReactiveOrigin
140
+ };