octane 0.2.12 → 0.2.13

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 (243) hide show
  1. package/README.md +5 -0
  2. package/dist/behavior-root.d.ts +13 -3
  3. package/dist/behavior-root.js +28 -5
  4. package/dist/cjs/behavior-root.cjs +32 -6
  5. package/dist/cjs/class-names.cjs +49 -0
  6. package/dist/cjs/constants.cjs +9 -0
  7. package/dist/cjs/css.cjs +6 -27
  8. package/dist/cjs/data-encoding.cjs +160 -0
  9. package/dist/cjs/dom-binding-handoff.cjs +93 -0
  10. package/dist/cjs/dom-binding-protocol.cjs +115 -0
  11. package/dist/cjs/dom-binding-styles.cjs +292 -0
  12. package/dist/cjs/dom-bindings.cjs +700 -0
  13. package/dist/cjs/dom-focused-move.cjs +66 -0
  14. package/dist/cjs/dom-tables.cjs +4 -94
  15. package/dist/cjs/error-codes.client.generated.cjs +33 -0
  16. package/dist/cjs/error-codes.server.generated.cjs +19 -0
  17. package/dist/cjs/hydration/control-capture.cjs +244 -0
  18. package/dist/cjs/hydration/event-capture.cjs +125 -43
  19. package/dist/cjs/hydration/interaction-config.cjs +50 -2
  20. package/dist/cjs/hydration-markers.cjs +37 -0
  21. package/dist/cjs/independent-hydration-protocol.cjs +106 -0
  22. package/dist/cjs/index.cjs +6 -0
  23. package/dist/cjs/runtime.cjs +2791 -215
  24. package/dist/cjs/runtime.server.cjs +716 -76
  25. package/dist/cjs/server/early-signals.cjs +45 -0
  26. package/dist/cjs/server/index.cjs +44 -0
  27. package/dist/cjs/server/rpc-batch.cjs +149 -0
  28. package/dist/cjs/server/rpc-stream.cjs +146 -0
  29. package/dist/cjs/server/rpc.cjs +34 -15
  30. package/dist/cjs/server/signal-query-observation.cjs +158 -0
  31. package/dist/cjs/server/streamed-region.cjs +52 -0
  32. package/dist/cjs/server/streamed-signals.cjs +512 -0
  33. package/dist/cjs/server-call.cjs +103 -0
  34. package/dist/cjs/server-rpc-batch-client.cjs +141 -0
  35. package/dist/cjs/server-rpc-client.cjs +94 -27
  36. package/dist/cjs/server-rpc-protocol.cjs +141 -0
  37. package/dist/cjs/server-rpc-stream-client.cjs +118 -0
  38. package/dist/cjs/signals/actions.cjs +474 -0
  39. package/dist/cjs/signals/client.cjs +4 -1
  40. package/dist/cjs/signals/computations.cjs +460 -0
  41. package/dist/cjs/signals/control-binding.cjs +368 -0
  42. package/dist/cjs/signals/derived-facade.cjs +50 -0
  43. package/dist/cjs/signals/document-owner.cjs +71 -0
  44. package/dist/cjs/signals/early-values.cjs +155 -0
  45. package/dist/cjs/signals/encoding.cjs +6 -95
  46. package/dist/cjs/signals/engine.cjs +276 -12
  47. package/dist/cjs/signals/errors.cjs +18 -0
  48. package/dist/cjs/signals/facade.cjs +477 -0
  49. package/dist/cjs/signals/graph.cjs +163 -20
  50. package/dist/cjs/signals/handle-protocol.cjs +36 -0
  51. package/dist/cjs/signals/index.cjs +81 -2
  52. package/dist/cjs/signals/native-read-client.cjs +10 -0
  53. package/dist/cjs/signals/owner-context.cjs +112 -0
  54. package/dist/cjs/signals/query-attempt-observer.cjs +68 -0
  55. package/dist/cjs/signals/query-facade.cjs +72 -0
  56. package/dist/cjs/signals/read-protocol.cjs +32 -0
  57. package/dist/cjs/signals/requests.cjs +287 -14
  58. package/dist/cjs/signals/scalar-computations.cjs +76 -0
  59. package/dist/cjs/signals/server.cjs +4 -1
  60. package/dist/cjs/signals/transition-candidate.cjs +567 -0
  61. package/dist/cjs/signals/transition-state.cjs +106 -0
  62. package/dist/cjs/signals/types.cjs +50 -0
  63. package/dist/cjs/stream-protocol.cjs +3 -0
  64. package/dist/cjs/streamed-signals-protocol.cjs +159 -0
  65. package/dist/cjs/style-values.cjs +122 -0
  66. package/dist/cjs/version.cjs +1 -1
  67. package/dist/class-names.d.ts +5 -0
  68. package/dist/class-names.js +25 -0
  69. package/dist/compiler/bundler.js +34 -6
  70. package/dist/compiler/compile.js +2234 -559
  71. package/dist/compiler/dom-binding-program.js +935 -0
  72. package/dist/compiler/dom-binding-request.js +57 -0
  73. package/dist/compiler/dom-bindings.js +2245 -0
  74. package/dist/compiler/hook-deps.js +26 -0
  75. package/dist/compiler/hydrate-boundaries.js +358 -15
  76. package/dist/compiler/index.d.ts +38 -1
  77. package/dist/compiler/index.js +1 -0
  78. package/dist/compiler/native-attribute-reads.js +127 -0
  79. package/dist/compiler/native-read-diagnostics.js +48 -9
  80. package/dist/compiler/native-read-types.js +55 -32
  81. package/dist/compiler/server-context.js +118 -0
  82. package/dist/compiler/signal-attempt-reads.js +479 -0
  83. package/dist/compiler/signal-declarations.js +557 -0
  84. package/dist/compiler/signal-start-reads.js +413 -0
  85. package/dist/compiler/slot-hooks.js +57 -10
  86. package/dist/compiler/template-ir.js +200 -0
  87. package/dist/compiler/typescript.d.ts +2 -0
  88. package/dist/compiler/typescript.js +2 -0
  89. package/dist/compiler/vite.d.ts +3 -1
  90. package/dist/compiler/vite.js +122 -4
  91. package/dist/compiler/volar.d.ts +6 -1
  92. package/dist/compiler/volar.js +674 -143
  93. package/dist/constants.d.ts +1 -0
  94. package/dist/constants.js +10 -0
  95. package/dist/css.d.ts +2 -5
  96. package/dist/css.js +2 -23
  97. package/dist/data-encoding.d.ts +9 -0
  98. package/dist/data-encoding.js +134 -0
  99. package/dist/dom-binding-classes.d.ts +15 -0
  100. package/dist/dom-binding-classes.js +129 -0
  101. package/dist/dom-binding-controls.d.ts +2 -0
  102. package/dist/dom-binding-controls.js +6 -0
  103. package/dist/dom-binding-handoff.d.ts +55 -0
  104. package/dist/dom-binding-handoff.js +62 -0
  105. package/dist/dom-binding-program.d.ts +300 -0
  106. package/dist/dom-binding-program.js +1625 -0
  107. package/dist/dom-binding-projections.d.ts +15 -0
  108. package/dist/dom-binding-projections.js +187 -0
  109. package/dist/dom-binding-protocol.d.ts +13 -0
  110. package/dist/dom-binding-protocol.js +88 -0
  111. package/dist/dom-binding-signals.d.ts +21 -0
  112. package/dist/dom-binding-signals.js +109 -0
  113. package/dist/dom-binding-styles.d.ts +17 -0
  114. package/dist/dom-binding-styles.js +272 -0
  115. package/dist/dom-bindings.d.ts +89 -0
  116. package/dist/dom-bindings.js +670 -0
  117. package/dist/dom-focused-move.d.ts +6 -0
  118. package/dist/dom-focused-move.js +42 -0
  119. package/dist/dom-tables.d.ts +1 -3
  120. package/dist/dom-tables.js +1 -91
  121. package/dist/error-codes.client.generated.d.ts +9 -0
  122. package/dist/error-codes.client.generated.js +33 -0
  123. package/dist/error-codes.server.generated.d.ts +5 -0
  124. package/dist/error-codes.server.generated.js +19 -0
  125. package/dist/hydration/control-capture.d.ts +62 -0
  126. package/dist/hydration/control-capture.js +223 -0
  127. package/dist/hydration/document-lifecycle.d.ts +23 -0
  128. package/dist/hydration/document-lifecycle.js +80 -0
  129. package/dist/hydration/event-capture.d.ts +20 -1
  130. package/dist/hydration/event-capture.js +128 -42
  131. package/dist/hydration/independent-island.d.ts +45 -0
  132. package/dist/hydration/independent-island.js +233 -0
  133. package/dist/hydration/index.d.ts +8 -1
  134. package/dist/hydration/index.js +55 -1
  135. package/dist/hydration/interaction-config.d.ts +5 -0
  136. package/dist/hydration/interaction-config.js +44 -1
  137. package/dist/hydration/stream-delivery.d.ts +32 -0
  138. package/dist/hydration/stream-delivery.js +333 -0
  139. package/dist/hydration/stream-receiver.d.ts +26 -0
  140. package/dist/hydration/stream-receiver.js +204 -0
  141. package/dist/hydration/stream-result-receiver.d.ts +70 -0
  142. package/dist/hydration/stream-result-receiver.js +246 -0
  143. package/dist/hydration/streamed-signals.d.ts +44 -0
  144. package/dist/hydration/streamed-signals.js +186 -0
  145. package/dist/hydration/types.d.ts +6 -0
  146. package/dist/hydration-markers.d.ts +7 -0
  147. package/dist/hydration-markers.js +10 -0
  148. package/dist/independent-hydration-protocol.d.ts +31 -0
  149. package/dist/independent-hydration-protocol.js +80 -0
  150. package/dist/index.d.ts +2 -0
  151. package/dist/index.js +4 -0
  152. package/dist/internal/signal-read.d.ts +1 -0
  153. package/dist/internal/signal-read.js +4 -0
  154. package/dist/jsx-runtime.d.ts +45 -6
  155. package/dist/public-types.d.ts +15 -1
  156. package/dist/runtime.d.ts +259 -21
  157. package/dist/runtime.js +2812 -220
  158. package/dist/runtime.server.d.ts +86 -6
  159. package/dist/runtime.server.js +712 -76
  160. package/dist/server/early-signals.d.ts +14 -0
  161. package/dist/server/early-signals.js +34 -0
  162. package/dist/server/index.d.ts +10 -2
  163. package/dist/server/index.js +48 -1
  164. package/dist/server/rpc-batch.d.ts +17 -0
  165. package/dist/server/rpc-batch.js +129 -0
  166. package/dist/server/rpc-stream.d.ts +9 -0
  167. package/dist/server/rpc-stream.js +125 -0
  168. package/dist/server/rpc.d.ts +5 -1
  169. package/dist/server/rpc.js +37 -13
  170. package/dist/server/signal-query-observation.d.ts +3 -0
  171. package/dist/server/signal-query-observation.js +134 -0
  172. package/dist/server/streamed-region.d.ts +15 -0
  173. package/dist/server/streamed-region.js +30 -0
  174. package/dist/server/streamed-signals.d.ts +45 -0
  175. package/dist/server/streamed-signals.js +488 -0
  176. package/dist/server-call.d.ts +41 -0
  177. package/dist/server-call.js +75 -0
  178. package/dist/server-rpc-batch-client.d.ts +7 -0
  179. package/dist/server-rpc-batch-client.js +119 -0
  180. package/dist/server-rpc-client.d.ts +3 -1
  181. package/dist/server-rpc-client.js +99 -27
  182. package/dist/server-rpc-protocol.d.ts +47 -0
  183. package/dist/server-rpc-protocol.js +109 -0
  184. package/dist/server-rpc-stream-client.d.ts +5 -0
  185. package/dist/server-rpc-stream-client.js +98 -0
  186. package/dist/signals/actions.d.ts +12 -0
  187. package/dist/signals/actions.js +466 -0
  188. package/dist/signals/client.d.ts +2 -0
  189. package/dist/signals/client.js +1 -0
  190. package/dist/signals/computations.d.ts +37 -0
  191. package/dist/signals/computations.js +455 -0
  192. package/dist/signals/control-binding.d.ts +31 -0
  193. package/dist/signals/control-binding.js +353 -0
  194. package/dist/signals/derived-facade.d.ts +3 -0
  195. package/dist/signals/derived-facade.js +25 -0
  196. package/dist/signals/document-owner.d.ts +10 -0
  197. package/dist/signals/document-owner.js +43 -0
  198. package/dist/signals/early-values.d.ts +24 -0
  199. package/dist/signals/early-values.js +124 -0
  200. package/dist/signals/encoding.d.ts +1 -3
  201. package/dist/signals/encoding.js +3 -93
  202. package/dist/signals/engine.d.ts +53 -4
  203. package/dist/signals/engine.js +275 -16
  204. package/dist/signals/errors.d.ts +7 -0
  205. package/dist/signals/errors.js +16 -0
  206. package/dist/signals/facade.d.ts +74 -0
  207. package/dist/signals/facade.js +452 -0
  208. package/dist/signals/graph.d.ts +50 -5
  209. package/dist/signals/graph.js +170 -19
  210. package/dist/signals/handle-protocol.d.ts +4 -0
  211. package/dist/signals/handle-protocol.js +11 -0
  212. package/dist/signals/index.d.ts +12 -3
  213. package/dist/signals/index.js +71 -2
  214. package/dist/signals/native-read-client.d.ts +3 -0
  215. package/dist/signals/native-read-client.js +10 -0
  216. package/dist/signals/owner-context.d.ts +22 -0
  217. package/dist/signals/owner-context.js +77 -0
  218. package/dist/signals/query-attempt-observer.d.ts +49 -0
  219. package/dist/signals/query-attempt-observer.js +41 -0
  220. package/dist/signals/query-facade.d.ts +3 -0
  221. package/dist/signals/query-facade.js +49 -0
  222. package/dist/signals/read-protocol.d.ts +32 -3
  223. package/dist/signals/read-protocol.js +26 -0
  224. package/dist/signals/requests.d.ts +38 -5
  225. package/dist/signals/requests.js +298 -15
  226. package/dist/signals/scalar-computations.d.ts +2 -0
  227. package/dist/signals/scalar-computations.js +60 -0
  228. package/dist/signals/server.d.ts +2 -0
  229. package/dist/signals/server.js +1 -0
  230. package/dist/signals/transition-candidate.d.ts +71 -0
  231. package/dist/signals/transition-candidate.js +557 -0
  232. package/dist/signals/transition-state.d.ts +51 -0
  233. package/dist/signals/transition-state.js +70 -0
  234. package/dist/signals/types.d.ts +95 -5
  235. package/dist/signals/types.js +20 -0
  236. package/dist/stream-protocol.d.ts +0 -5
  237. package/dist/stream-protocol.js +3 -0
  238. package/dist/streamed-signals-protocol.d.ts +60 -0
  239. package/dist/streamed-signals-protocol.js +130 -0
  240. package/dist/style-values.d.ts +3 -0
  241. package/dist/style-values.js +96 -0
  242. package/dist/version.js +1 -1
  243. package/package.json +37 -1
@@ -20,12 +20,17 @@ var requests_exports = {};
20
20
  __export(requests_exports, {
21
21
  RequestEntry: () => RequestEntry,
22
22
  ResourceBinding: () => ResourceBinding,
23
+ createResource: () => createResource,
23
24
  initializeResource: () => initializeResource,
24
25
  query: () => query
25
26
  });
26
27
  module.exports = __toCommonJS(requests_exports);
27
28
  var import_encoding = require("./encoding.cjs");
29
+ var import_engine = require("./engine.cjs");
30
+ var import_errors = require("./errors.cjs");
28
31
  var import_graph = require("./graph.cjs");
32
+ var import_types = require("./types.cjs");
33
+ var import_query_attempt_observer = require("./query-attempt-observer.cjs");
29
34
  class Request {
30
35
  constructor(definition, argument) {
31
36
  this.definition = definition;
@@ -36,6 +41,9 @@ class Request {
36
41
  Object.freeze(this);
37
42
  }
38
43
  definition;
44
+ get [import_types.QUERY_REQUEST]() {
45
+ return void 0;
46
+ }
39
47
  queryKey;
40
48
  identity;
41
49
  argument;
@@ -54,16 +62,24 @@ function query(key, load, options) {
54
62
  });
55
63
  return Object.freeze(describe);
56
64
  }
57
- function makeAttempt(entry) {
65
+ function createResource(owner, key, describe) {
66
+ return (0, import_engine.createResourceCellWith)(owner, key, describe, initializeResource, true);
67
+ }
68
+ function makeAttempt(entry, generation, streamed = false) {
58
69
  let resolve;
59
70
  const settled = new Promise((done) => {
60
71
  resolve = done;
61
72
  });
62
73
  return {
63
74
  entry,
64
- controller: new AbortController(),
75
+ controller: streamed ? void 0 : new AbortController(),
65
76
  iterator: void 0,
66
77
  settled,
78
+ generation,
79
+ streamed,
80
+ result: void 0,
81
+ observations: void 0,
82
+ sequence: 0,
67
83
  resolve,
68
84
  hasYielded: false
69
85
  };
@@ -87,13 +103,33 @@ class RequestEntry {
87
103
  get active() {
88
104
  return this.attempt !== void 0;
89
105
  }
106
+ get attemptGeneration() {
107
+ return this.generation;
108
+ }
109
+ observe(nodeKey) {
110
+ const attempt = this.attempt;
111
+ if (!attempt || attempt.streamed) return;
112
+ const context = (0, import_query_attempt_observer.serverSignalQueryAttemptObserver)(this.owner.scopeKey);
113
+ if (context === void 0) return;
114
+ const observations = attempt.observations ??= context.createObservations();
115
+ observations.observe(context, {
116
+ nodeKey,
117
+ selectionKey: this.request.identity,
118
+ attempt: attempt.generation,
119
+ kind: this.request.definition.kind,
120
+ result: attempt.result,
121
+ isCurrent: () => currentEntry(attempt) === this
122
+ });
123
+ return attempt;
124
+ }
90
125
  start(pending) {
126
+ if (this.owner.readBarrier !== void 0) return;
91
127
  const generation = ++this.generation;
92
128
  this.stopAttempt();
93
- if (generation !== this.generation || this.owner.retired || this.owner.requests.get(this.request.identity) !== this || !this.consumers.size)
129
+ if (generation !== this.generation || this.owner.readBarrier !== void 0 || this.owner.retired || this.owner.requests.get(this.request.identity) !== this || !this.consumers.size)
94
130
  return;
95
131
  const previous = this.state.snapshot;
96
- const attempt = this.attempt = makeAttempt(this);
132
+ const attempt = this.attempt = makeAttempt(this, generation);
97
133
  const connection = this.request.definition.kind === "stream" ? "connecting" : "none";
98
134
  this.state = !pending && previous.status === "ready" ? (0, import_graph.readyState)(previous.value, {
99
135
  refreshing: true,
@@ -107,7 +143,8 @@ class RequestEntry {
107
143
  result = (0, import_graph.untrack)(
108
144
  () => (0, import_graph.signalBatch)(
109
145
  () => this.request.definition.load(this.request.argument, {
110
- signal: attempt.controller.signal
146
+ signal: attempt.controller.signal,
147
+ ...previous.status === "ready" ? { previous: previous.value } : {}
111
148
  })
112
149
  )
113
150
  );
@@ -116,7 +153,73 @@ class RequestEntry {
116
153
  return;
117
154
  }
118
155
  if (this.request.definition.kind === "stream") observeStream(attempt, result);
119
- else observePromise(attempt, result);
156
+ else {
157
+ if (currentEntry(attempt)) attempt.result = result;
158
+ observePromise(attempt, result);
159
+ }
160
+ }
161
+ startStreamed(identity) {
162
+ if (this.owner.readBarrier !== void 0 || identity.selectionKey !== this.request.identity || identity.attempt < this.generation || this.attempt === void 0 && identity.attempt === this.generation && this.state.snapshot.status !== "pending" || this.owner.retired || !this.consumers.size) {
163
+ return false;
164
+ }
165
+ if (this.attempt?.streamed && this.attempt.generation === identity.attempt) {
166
+ return true;
167
+ }
168
+ this.generation = identity.attempt;
169
+ this.stopAttempt();
170
+ if (this.generation !== identity.attempt || this.owner.readBarrier !== void 0 || this.owner.retired || this.owner.requests.get(this.request.identity) !== this || !this.consumers.size) {
171
+ return false;
172
+ }
173
+ this.attempt = makeAttempt(this, identity.attempt, true);
174
+ return true;
175
+ }
176
+ acceptStreamed(frame) {
177
+ const attempt = this.attempt;
178
+ if (!attempt?.streamed || attempt.generation !== frame.identity.attempt || frame.sequence !== attempt.sequence || currentEntry(attempt) !== this) {
179
+ return false;
180
+ }
181
+ attempt.sequence++;
182
+ (0, import_graph.signalBatch)(() => {
183
+ if (frame.kind === "open") return;
184
+ if (frame.kind === "value") {
185
+ attempt.hasYielded = true;
186
+ this.state = (0, import_graph.readyState)((0, import_encoding.decodeSignalValue)(frame.value), {
187
+ requestKey: this.request.identity,
188
+ connection: this.request.definition.kind === "stream" ? "open" : "none",
189
+ complete: false
190
+ });
191
+ this.deliver();
192
+ return;
193
+ }
194
+ if (frame.kind === "error") {
195
+ this.state = (0, import_graph.errorState)(
196
+ new import_errors.SignalStreamError(frame.code),
197
+ this.request.definition.kind === "stream" ? "closed" : "none",
198
+ this.request.identity
199
+ );
200
+ completeAttempt(attempt);
201
+ this.deliver();
202
+ return;
203
+ }
204
+ if (!attempt.hasYielded || this.state.snapshot.status !== "ready") {
205
+ this.state = (0, import_graph.errorState)(
206
+ new Error("The streamed signal completed without yielding a value."),
207
+ this.request.definition.kind === "stream" ? "closed" : "none",
208
+ this.request.identity
209
+ );
210
+ completeAttempt(attempt);
211
+ this.deliver();
212
+ return;
213
+ }
214
+ this.state = (0, import_graph.readyState)(this.state.snapshot.value, {
215
+ requestKey: this.request.identity,
216
+ connection: this.request.definition.kind === "stream" ? "closed" : "none",
217
+ complete: true
218
+ });
219
+ completeAttempt(attempt);
220
+ this.deliver();
221
+ });
222
+ return true;
120
223
  }
121
224
  deliver() {
122
225
  for (const consumer of this.consumers) consumer.deliver();
@@ -130,8 +233,10 @@ class RequestEntry {
130
233
  const iterator = attempt.iterator;
131
234
  attempt.controller = void 0;
132
235
  attempt.iterator = void 0;
236
+ attempt.result = void 0;
237
+ attempt.observations?.retire();
133
238
  attempt.resolve();
134
- if (controller) (0, import_graph.untrack)(() => (0, import_graph.signalBatch)(() => controller.abort()));
239
+ if (controller) (0, import_graph.untrackCommitted)(() => (0, import_graph.signalBatch)(() => controller.abort()));
135
240
  if (iterator) closeIterator(iterator);
136
241
  }
137
242
  remove(consumer) {
@@ -148,11 +253,13 @@ function currentEntry(attempt) {
148
253
  return entry && !entry.owner.retired && entry.attempt === attempt ? entry : void 0;
149
254
  }
150
255
  function completeAttempt(attempt) {
256
+ attempt.observations?.complete();
151
257
  const entry = attempt.entry;
152
258
  if (entry?.attempt === attempt) entry.attempt = void 0;
153
259
  attempt.entry = void 0;
154
260
  attempt.controller = void 0;
155
261
  attempt.iterator = void 0;
262
+ attempt.result = void 0;
156
263
  attempt.resolve();
157
264
  }
158
265
  function observePromise(attempt, result) {
@@ -172,6 +279,7 @@ function observePromise(attempt, result) {
172
279
  function failAttempt(attempt, error) {
173
280
  const entry = currentEntry(attempt);
174
281
  if (!entry) return;
282
+ attempt.observations?.fail(error);
175
283
  (0, import_graph.signalBatch)(() => {
176
284
  const iterator = attempt.iterator;
177
285
  entry.state = (0, import_graph.errorState)(
@@ -188,7 +296,7 @@ function ignoreRetiredCloseFailure() {
188
296
  }
189
297
  function closeIterator(iterator) {
190
298
  try {
191
- const result = (0, import_graph.untrack)(() => (0, import_graph.signalBatch)(() => iterator.return?.()));
299
+ const result = (0, import_graph.untrackCommitted)(() => (0, import_graph.signalBatch)(() => iterator.return?.()));
192
300
  Promise.resolve(result).catch(ignoreRetiredCloseFailure);
193
301
  } catch {
194
302
  }
@@ -284,7 +392,9 @@ function receiveStreamStep(attempt, result) {
284
392
  });
285
393
  accepted.deliver();
286
394
  });
287
- nextStreamStep(attempt);
395
+ const observed = attempt.observations?.publish(value);
396
+ if (observed === void 0) nextStreamStep(attempt);
397
+ else observed.then(() => nextStreamStep(attempt));
288
398
  }
289
399
  class ResourceBinding {
290
400
  constructor(owner, node, describe, seed, retained = seed) {
@@ -298,7 +408,11 @@ class ResourceBinding {
298
408
  kind: identity.kind,
299
409
  argument: (0, import_encoding.decodeSignalValue)(identity.argument)
300
410
  } : void 0;
301
- node.compute = () => this.compute();
411
+ node.compute = () => {
412
+ const pending = this.pendingObserver;
413
+ this.pendingObserver = void 0;
414
+ return pending === void 0 || (0, import_query_attempt_observer.hasServerSignalQueryAttemptObserver)(this.owner.scopeKey) ? this.compute() : pending(() => this.compute());
415
+ };
302
416
  node.retry = (options) => this.retry(options);
303
417
  }
304
418
  owner;
@@ -309,18 +423,92 @@ class ResourceBinding {
309
423
  retainedRequest;
310
424
  seeded;
311
425
  describedAttempt;
426
+ observedAttempt;
427
+ pendingObserver;
312
428
  pendingPromise;
313
429
  resolvePending;
430
+ streamedSelection;
431
+ selectionAuthority = {};
314
432
  request() {
315
433
  const request = (0, import_graph.pure)(() => this.describe());
434
+ if (request === import_types.skip) return request;
316
435
  if (!(request instanceof Request))
317
- throw new TypeError("asyncSignal$ must describe a query request.");
436
+ throw new TypeError("A resource must describe a query request.");
318
437
  return request;
319
438
  }
439
+ forkCandidate(target) {
440
+ if (this.streamedSelection || this.owner.streamedSelections?.has(this.node.key)) {
441
+ throw new import_graph.CandidateUnsupportedError(
442
+ "Streamed candidates are not supported by this prototype."
443
+ );
444
+ }
445
+ const fork = new ResourceBinding(this.owner, target, this.describe);
446
+ fork.candidate = true;
447
+ fork.retainedRequest = this.retainedRequest;
448
+ return {
449
+ dispose: () => fork.dispose(),
450
+ prepare: () => {
451
+ if (this.streamedSelection || this.owner.streamedSelections?.has(this.node.key))
452
+ return { status: "invalid" };
453
+ const entry = fork.selected;
454
+ const attempt = entry?.attempt;
455
+ if (entry) {
456
+ if (attempt?.streamed) return { status: "invalid" };
457
+ const snapshot = entry.state.snapshot;
458
+ if (attempt && (entry.request.definition.kind !== "stream" || snapshot.status !== "ready"))
459
+ return { status: "pending", waiting: target.state?.waiting ?? attempt.settled };
460
+ if (!(snapshot.status === "ready" && (snapshot.complete || entry.request.definition.kind === "stream") || snapshot.status === "error"))
461
+ return { status: "invalid" };
462
+ } else if (target.state?.snapshot.status !== "idle") {
463
+ const state2 = target.state;
464
+ if (state2?.snapshot.status === "error")
465
+ return { status: "error", error: state2.snapshot.error };
466
+ if (state2?.waiting) return { status: "pending", waiting: state2.waiting };
467
+ return { status: "invalid" };
468
+ }
469
+ const state = entry?.state;
470
+ const authority = this.selectionAuthority;
471
+ const forkAuthority = fork.selectionAuthority;
472
+ return {
473
+ status: "ready",
474
+ receipt: {
475
+ validate: () => !this.streamedSelection && !this.owner.streamedSelections?.has(this.node.key) && this.selectionAuthority === authority && fork.selectionAuthority === forkAuthority && fork.selected === entry && (entry ? entry.state === state && entry.attempt === attempt && entry.consumers.has(fork) : target.state?.snapshot.status === "idle"),
476
+ publish: () => {
477
+ const previous = this.selected;
478
+ const resolve = this.resolvePending;
479
+ entry?.consumers.add(this);
480
+ entry?.consumers.delete(fork);
481
+ this.selected = entry;
482
+ this.selectedIdentity = fork.selectedIdentity;
483
+ this.retainedRequest = fork.retainedRequest;
484
+ this.describedAttempt = fork.describedAttempt;
485
+ this.observedAttempt = fork.observedAttempt;
486
+ this.selectionAuthority = fork.selectionAuthority;
487
+ this.pendingObserver = void 0;
488
+ this.pendingPromise = void 0;
489
+ this.resolvePending = void 0;
490
+ this.seeded = void 0;
491
+ fork.selected = void 0;
492
+ return () => {
493
+ resolve?.();
494
+ if (previous !== entry && previous !== this.selected) previous?.remove(this);
495
+ };
496
+ }
497
+ }
498
+ };
499
+ }
500
+ };
501
+ }
320
502
  compute() {
321
503
  let request;
322
504
  try {
323
- request = this.request();
505
+ const described = this.request();
506
+ if (described === import_types.skip) {
507
+ this.detach();
508
+ this.seeded = void 0;
509
+ return (0, import_graph.idleState)();
510
+ }
511
+ request = described;
324
512
  const previousDefinition = this.owner.queryDefinitions.get(request.queryKey);
325
513
  if (previousDefinition && (previousDefinition.load !== request.definition.load || previousDefinition.kind !== request.definition.kind)) {
326
514
  throw new TypeError(
@@ -329,12 +517,18 @@ class ResourceBinding {
329
517
  }
330
518
  this.owner.queryDefinitions.set(request.queryKey, request.definition);
331
519
  } catch (error) {
520
+ if ((0, import_graph.isThenable)(error)) {
521
+ this.pendingObserver = (0, import_query_attempt_observer.captureCurrentServerSignalQueryAttemptObserver)(this.owner.scopeKey);
522
+ }
332
523
  this.detach();
333
524
  throw error;
334
525
  }
335
526
  if (this.selected?.request.identity !== request.identity) {
336
527
  this.detach();
337
528
  (0, import_graph.assertAlive)(this.owner);
529
+ if (this.candidate && this.describe === void 0) {
530
+ throw new TypeError("The signal candidate has retired.");
531
+ }
338
532
  this.selectedIdentity = {
339
533
  queryKey: request.queryKey,
340
534
  kind: request.definition.kind,
@@ -356,8 +550,19 @@ class ResourceBinding {
356
550
  this.selected = entry;
357
551
  entry.consumers.add(this);
358
552
  this.owner.trace("select", this.node);
359
- if (start) entry.start(entry.state.snapshot.status !== "ready");
553
+ const streamed = this.candidate ? void 0 : this.owner.streamedSelections?.get(this.node.key);
554
+ if (streamed && streamed.selectionKey !== request.identity) {
555
+ this.owner.discardCompletedStreamedSelection?.(streamed);
556
+ }
557
+ if (streamed?.selectionKey === request.identity && entry.startStreamed(streamed)) {
558
+ this.streamedSelection = streamed;
559
+ this.owner.streamedSelectionReady?.(this);
560
+ entry.deliver();
561
+ } else if (start) {
562
+ entry.start(entry.state.snapshot.status !== "ready");
563
+ }
360
564
  }
565
+ this.observeSelectedAttempt();
361
566
  (0, import_graph.assertAlive)(this.owner);
362
567
  return this.state();
363
568
  }
@@ -395,17 +600,65 @@ class ResourceBinding {
395
600
  }
396
601
  detach() {
397
602
  const entry = this.selected;
603
+ if (!this.candidate && this.streamedSelection === this.owner.streamedSelections?.get(this.node.key)) {
604
+ this.owner.streamedSelections?.delete(this.node.key);
605
+ }
398
606
  this.selected = void 0;
399
607
  this.selectedIdentity = void 0;
400
608
  this.describedAttempt = void 0;
609
+ this.observedAttempt = void 0;
401
610
  this.resolvePending?.();
402
611
  this.resolvePending = void 0;
403
612
  this.pendingPromise = void 0;
613
+ this.streamedSelection = void 0;
614
+ this.selectionAuthority = {};
404
615
  entry?.remove(this);
405
616
  }
617
+ observeSelectedAttempt() {
618
+ const attempt = this.selected?.attempt;
619
+ if (!attempt || attempt === this.observedAttempt) return;
620
+ if (this.selected.observe(this.node.key) === attempt) this.observedAttempt = attempt;
621
+ }
622
+ get authority() {
623
+ return this.selected ? this.selectionAuthority : void 0;
624
+ }
625
+ isStreamedSelectionReady(identity) {
626
+ return this.streamedSelection === identity && this.selected?.request.identity === identity.selectionKey;
627
+ }
628
+ bindStreamedSelection(identity) {
629
+ (0, import_graph.assertAlive)(this.owner);
630
+ const entry = this.selected;
631
+ if (identity.nodeKey !== this.node.key) return false;
632
+ if (!entry || entry.request.identity !== identity.selectionKey) {
633
+ this.streamedSelection = void 0;
634
+ return true;
635
+ }
636
+ if (!entry.startStreamed(identity)) return false;
637
+ this.streamedSelection = identity;
638
+ entry.deliver();
639
+ return true;
640
+ }
641
+ acceptStreamed(frame) {
642
+ const identity = this.streamedSelection;
643
+ const entry = this.selected;
644
+ if (!identity || !entry || identity.nodeKey !== frame.identity.nodeKey || identity.selectionKey !== frame.identity.selectionKey || identity.selectionGeneration !== frame.identity.selectionGeneration || identity.attempt !== frame.identity.attempt || frame.kind === "open" && frame.resource !== entry.request.definition.kind) {
645
+ return false;
646
+ }
647
+ return entry.acceptStreamed(frame);
648
+ }
649
+ failStreamed(identity, error) {
650
+ const streamed = this.streamedSelection;
651
+ const entry = this.selected;
652
+ if (!streamed || !entry || streamed.nodeKey !== identity.nodeKey || streamed.selectionKey !== identity.selectionKey || streamed.selectionGeneration !== identity.selectionGeneration || streamed.attempt !== identity.attempt || entry.attempt?.generation !== identity.attempt || !entry.attempt.streamed) {
653
+ return false;
654
+ }
655
+ failAttempt(entry.attempt, error);
656
+ return true;
657
+ }
406
658
  retry(options) {
407
659
  (0, import_graph.assertAlive)(this.owner);
408
660
  (0, import_graph.assertWritable)();
661
+ if (!this.selected && this.node.state?.snapshot.status === "idle") return;
409
662
  (0, import_graph.signalBatch)(() => {
410
663
  const previous = this.selected;
411
664
  if (!previous) (0, import_graph.invalidateNode)(this.node);
@@ -415,7 +668,23 @@ class ResourceBinding {
415
668
  }
416
669
  this.owner.trace("retry", this.node);
417
670
  if (this.selected === previous) this.selected.start(options?.pending === true);
671
+ this.observeSelectedAttempt();
672
+ });
673
+ }
674
+ adopt(requestKey, value) {
675
+ (0, import_graph.assertAlive)(this.owner);
676
+ (0, import_graph.assertWritable)();
677
+ const entry = this.selected;
678
+ if (!entry || entry.request.identity !== requestKey) return false;
679
+ const streaming = entry.request.definition.kind === "stream";
680
+ if (!streaming) entry.stopAttempt();
681
+ entry.state = (0, import_graph.readyState)(value, {
682
+ requestKey: entry.request.identity,
683
+ connection: streaming ? entry.state.snapshot.connection : "none",
684
+ complete: streaming ? entry.state.snapshot.complete : true
418
685
  });
686
+ entry.deliver();
687
+ return true;
419
688
  }
420
689
  seedRequest(retained = false) {
421
690
  const request = retained ? this.retainedRequest : this.selectedIdentity;
@@ -427,13 +696,16 @@ class ResourceBinding {
427
696
  };
428
697
  }
429
698
  acceptsSeed(seed) {
430
- return matchesSeed(this.request(), seed);
699
+ const request = this.request();
700
+ return request !== import_types.skip && matchesSeed(request, seed);
431
701
  }
432
702
  dispose() {
433
703
  this.detach();
704
+ this.pendingObserver = void 0;
434
705
  this.describe = void 0;
435
706
  this.seeded = void 0;
436
707
  this.retainedRequest = void 0;
708
+ this.streamedSelection = void 0;
437
709
  }
438
710
  }
439
711
  function matchesSeed(request, seed) {
@@ -446,6 +718,7 @@ function initializeResource(owner, node, describe, seed, retained = seed) {
446
718
  0 && (module.exports = {
447
719
  RequestEntry,
448
720
  ResourceBinding,
721
+ createResource,
449
722
  initializeResource,
450
723
  query
451
724
  });
@@ -0,0 +1,76 @@
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
+ var scalar_computations_exports = {};
20
+ __export(scalar_computations_exports, {
21
+ createDeclaredScalarCell: () => createDeclaredScalarCell
22
+ });
23
+ module.exports = __toCommonJS(scalar_computations_exports);
24
+ var import_engine = require("./engine.cjs");
25
+ var import_graph = require("./graph.cjs");
26
+ class ScalarBinding {
27
+ constructor(owner, node, compute) {
28
+ this.owner = owner;
29
+ this.node = node;
30
+ this.compute = compute;
31
+ node.compute = (target) => {
32
+ if (owner.readBarrier !== void 0) {
33
+ this.frozen = true;
34
+ return target.state?.snapshot.status === "ready" ? target.state : (0, import_graph.pendingState)(owner.readBarrier);
35
+ }
36
+ let result;
37
+ try {
38
+ result = this.compute();
39
+ } catch (error) {
40
+ if ((0, import_graph.isThenable)(error)) throw error;
41
+ return (0, import_graph.errorState)(error);
42
+ }
43
+ return (0, import_graph.derivedValueState)(target, result);
44
+ };
45
+ }
46
+ owner;
47
+ node;
48
+ frozen = false;
49
+ compute;
50
+ forkCandidate(target) {
51
+ if (this.frozen || this.owner.readBarrier || !this.compute) {
52
+ throw new import_graph.CandidateUnsupportedError("Frozen scalar candidates are not supported.");
53
+ }
54
+ target.compute = this.node.compute;
55
+ }
56
+ suspend() {
57
+ return false;
58
+ }
59
+ resume() {
60
+ if (!this.frozen || this.owner.retired || this.owner.readBarrier !== void 0 || !this.compute)
61
+ return;
62
+ this.frozen = false;
63
+ (0, import_graph.invalidateNode)(this.node);
64
+ (0, import_graph.refreshNode)(this.node);
65
+ }
66
+ dispose() {
67
+ this.compute = void 0;
68
+ }
69
+ }
70
+ function createDeclaredScalarCell(owner, key, compute) {
71
+ return (0, import_engine.createDerivedCellWith)(owner, key, compute, void 0, ScalarBinding);
72
+ }
73
+ // Annotate the CommonJS export names for ESM import in node:
74
+ 0 && (module.exports = {
75
+ createDeclaredScalarCell
76
+ });
@@ -15,12 +15,14 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
20
  var server_exports = {};
20
21
  __export(server_exports, {
21
22
  useSignal$: () => useSignal$
22
23
  });
23
24
  module.exports = __toCommonJS(server_exports);
25
+ __reExport(server_exports, require("./index.cjs"), module.exports);
24
26
  var import_runtime_server = require("../runtime.server.cjs");
25
27
  var import_engine = require("./engine.cjs");
26
28
  function disposeLocalSignal(cell) {
@@ -41,5 +43,6 @@ function useSignal$(initial, slot) {
41
43
  }
42
44
  // Annotate the CommonJS export names for ESM import in node:
43
45
  0 && (module.exports = {
44
- useSignal$
46
+ useSignal$,
47
+ ...require("./index.cjs")
45
48
  });