octane 0.3.1 → 0.3.2

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 (45) hide show
  1. package/dist/cjs/constants.cjs +18 -25
  2. package/dist/cjs/css.cjs +6 -0
  3. package/dist/cjs/dom-binding-protocol.cjs +37 -14
  4. package/dist/cjs/hydration/control-capture.cjs +12 -4
  5. package/dist/cjs/hydration/event-capture.cjs +6 -7
  6. package/dist/cjs/hydration-markers.cjs +40 -2
  7. package/dist/cjs/runtime-tags.cjs +55 -0
  8. package/dist/cjs/runtime.cjs +136 -113
  9. package/dist/cjs/runtime.server.cjs +34 -41
  10. package/dist/cjs/server/streamed-signals.cjs +7 -4
  11. package/dist/cjs/signals/control-binding.cjs +2 -1
  12. package/dist/cjs/stream-protocol.cjs +9 -8
  13. package/dist/cjs/version.cjs +1 -1
  14. package/dist/compiler/compile.js +70 -17
  15. package/dist/compiler/dom-bindings.js +5 -0
  16. package/dist/constants.d.ts +7 -18
  17. package/dist/constants.js +11 -9
  18. package/dist/css.d.ts +7 -0
  19. package/dist/css.js +4 -0
  20. package/dist/dom-binding-program.js +12 -5
  21. package/dist/dom-binding-protocol.d.ts +14 -1
  22. package/dist/dom-binding-protocol.js +40 -14
  23. package/dist/hydration/control-capture.d.ts +2 -0
  24. package/dist/hydration/control-capture.js +18 -5
  25. package/dist/hydration/event-capture.js +1 -2
  26. package/dist/hydration/independent-island.js +5 -5
  27. package/dist/hydration-markers.d.ts +30 -0
  28. package/dist/hydration-markers.js +27 -1
  29. package/dist/react/index.js +1 -1
  30. package/dist/react/react-compat-shared.js +5 -3
  31. package/dist/react/shared.d.ts +1 -3
  32. package/dist/react/shared.js +1 -1
  33. package/dist/runtime-tags.d.ts +34 -0
  34. package/dist/runtime-tags.js +22 -0
  35. package/dist/runtime.d.ts +5 -14
  36. package/dist/runtime.js +116 -71
  37. package/dist/runtime.server.d.ts +2 -3
  38. package/dist/runtime.server.js +25 -17
  39. package/dist/server/streamed-signals.js +7 -4
  40. package/dist/signals/control-binding.js +4 -2
  41. package/dist/stream-protocol.js +20 -9
  42. package/dist/universal-core.js +8 -4
  43. package/dist/universal-native.js +1 -1
  44. package/dist/version.js +1 -1
  45. package/package.json +3 -3
@@ -160,6 +160,9 @@ function createStreamedRendererFrameStream(frames, options = {}) {
160
160
  function escapeAttribute(value) {
161
161
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
162
162
  }
163
+ function byteLength(value) {
164
+ return typeof globalThis.Buffer === "function" ? globalThis.Buffer.byteLength(value, "utf8") : new TextEncoder().encode(value).byteLength;
165
+ }
163
166
  function streamedRendererFrameScript(frame, nonce) {
164
167
  const encoded = encodeStreamedRendererFrameForScript(frame);
165
168
  return `<script ${STREAM_SCRIPT_ATTR}${nonce === void 0 ? "" : ` nonce="${escapeAttribute(nonce)}"`}>globalThis.__octaneStreamedRenderer.receive(${encoded});</script>`;
@@ -178,7 +181,7 @@ function createSignalInjection(identity, result, options, timeoutMessage) {
178
181
  let queued = options.announceSelection ? streamedSignalSelectionScript(identity, options.nonce) : "";
179
182
  let pending = false;
180
183
  let awaitingAcceptance = false;
181
- let queuedBytes = queued === "" ? 0 : new TextEncoder().encode(queued).byteLength;
184
+ let queuedBytes = queued === "" ? 0 : byteLength(queued);
182
185
  let finished = false;
183
186
  let subscribed = false;
184
187
  let totalBytes = 0;
@@ -224,7 +227,7 @@ function createSignalInjection(identity, result, options, timeoutMessage) {
224
227
  return;
225
228
  }
226
229
  const html = streamedRendererFrameScript(next.value, options.nonce);
227
- const bytes = new TextEncoder().encode(html).byteLength;
230
+ const bytes = byteLength(html);
228
231
  if (bytes > budget.maxFrameBytes || totalBytes + bytes > budget.maxTotalBytes) {
229
232
  fail(new Error("Streamed renderer injection exceeded its byte budget."));
230
233
  return;
@@ -341,7 +344,7 @@ function createAutomaticStreamedSignalInjection(options, external) {
341
344
  for (const { identity, attempt } of selections ?? []) {
342
345
  if (attempt.signal.aborted) continue;
343
346
  const script = streamedSignalSelectionScript(identity, options.nonce);
344
- const bytes = new TextEncoder().encode(script).byteLength;
347
+ const bytes = byteLength(script);
345
348
  if (bytes > budget.maxFrameBytes || totalBytes + bytes > budget.maxTotalBytes) {
346
349
  const error = new Error("Automatic streamed signals exceeded their byte budget.");
347
350
  fail(error);
@@ -374,7 +377,7 @@ function createAutomaticStreamedSignalInjection(options, external) {
374
377
  if (child.done && (child.attempt !== void 0 || renderComplete)) cleanupChild(child);
375
378
  continue;
376
379
  }
377
- const bytes = child.attempt === void 0 ? new TextEncoder().encode(html).byteLength : child.source.queuedBytes;
380
+ const bytes = child.attempt === void 0 ? byteLength(html) : child.source.queuedBytes;
378
381
  if (bytes > budget.maxFrameBytes || totalBytes + bytes > budget.maxTotalBytes) {
379
382
  fail(new Error("Automatic streamed signals exceeded their byte budget."));
380
383
  return;
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  consumeHydrationControl,
3
3
  initializeHydrationControlCapture,
4
- snapshotHydrationControl
4
+ snapshotHydrationControl,
5
+ isRestoredHydrationTextarea
5
6
  } from "../hydration/control-capture.js";
6
7
  import {
7
8
  hasHydrationControlSignalWriter,
@@ -254,7 +255,8 @@ function __createBindingControls(owner = currentSignalOwner()) {
254
255
  let snapshot;
255
256
  do {
256
257
  snapshot = snapshotHydrationControl(control);
257
- if (snapshot.editRevision > 0 && isWritableSignal(active)) write(nativeValue());
258
+ if (isWritableSignal(active) && (snapshot.editRevision > 0 || channel === "value" && isRestoredHydrationTextarea(control, read(active))))
259
+ write(nativeValue());
258
260
  if (disposed) return;
259
261
  } while (!consumeHydrationControl(control, snapshot.revision));
260
262
  },
@@ -1,13 +1,24 @@
1
- import { isBindingOpenComment } from "./dom-binding-protocol.js";
1
+ import {
2
+ BINDING_OPEN_PREFIX,
3
+ isBindingOpenComment,
4
+ isForBindingOpenComment
5
+ } from "./dom-binding-protocol.js";
6
+ import {
7
+ HYDRATION_END,
8
+ HYDRATION_FOR_EMPTY,
9
+ HYDRATION_FOR_ITEMS,
10
+ HYDRATION_FOR_PREFIX,
11
+ HYDRATION_START
12
+ } from "./hydration-markers.js";
2
13
  const STREAM_BOUNDARY_ATTR = "data-oct-b";
3
14
  const SUSPENSE_SCRIPT_ATTR = "data-octane-suspense";
4
15
  const STREAM_SCRIPT_ATTR = "data-octane-stream";
5
16
  const HYDRATE_STREAM_TOKEN_ATTR = "data-octane-stream-token";
6
17
  function hydrationMarkerMultiplicity(data, open) {
7
- const marker = open ? "[" : "]";
18
+ const marker = open ? HYDRATION_START : HYDRATION_END;
8
19
  if (data === marker) return 1;
9
- if (open && (data === "[f0" || data === "[f1")) return 1;
10
- if (open && (data.startsWith("[b;") || data.startsWith("[f")) && isBindingOpenComment(data))
20
+ if (open && (data === HYDRATION_FOR_EMPTY || data === HYDRATION_FOR_ITEMS)) return 1;
21
+ if (open && (data.startsWith(BINDING_OPEN_PREFIX) || data.startsWith(HYDRATION_FOR_PREFIX)) && isBindingOpenComment(data))
11
22
  return 1;
12
23
  if (data.length < 2 || data.charCodeAt(0) !== marker.charCodeAt(0)) return 0;
13
24
  const first = data.charCodeAt(1);
@@ -47,8 +58,8 @@ function getLeadingHydrationListRange(host) {
47
58
  let enclosingEnd = null;
48
59
  while (start !== null && start.nodeType === 8) {
49
60
  const data = start.data;
50
- const list = data === "[f0" || data === "[f1" || (data.startsWith("[f0;b;") || data.startsWith("[f1;b;")) && isBindingOpenComment(data);
51
- const wrapperMultiplicity = data === "[" ? 1 : data.charCodeAt(1) >= 49 && data.charCodeAt(1) <= 57 ? hydrationMarkerMultiplicity(data, true) : 0;
61
+ const list = data === HYDRATION_FOR_EMPTY || data === HYDRATION_FOR_ITEMS || isForBindingOpenComment(data);
62
+ const wrapperMultiplicity = data === HYDRATION_START ? 1 : data.charCodeAt(1) >= 49 && data.charCodeAt(1) <= 57 ? hydrationMarkerMultiplicity(data, true) : 0;
52
63
  if (!list && wrapperMultiplicity === 0) return null;
53
64
  const end = rendererRangeClose(start);
54
65
  if (end === null || enclosingEnd !== null && (end.compareDocumentPosition(enclosingEnd) & 4) === 0)
@@ -56,12 +67,12 @@ function getLeadingHydrationListRange(host) {
56
67
  if (hydrationMarkerMultiplicity(end.data, false) !== (list ? 1 : wrapperMultiplicity))
57
68
  return null;
58
69
  if (list) {
59
- const suffix = data.slice(3);
70
+ const suffix = data.slice(HYDRATION_FOR_EMPTY.length);
60
71
  return {
61
72
  start,
62
73
  end,
63
- emptyMarker: "[f0" + suffix,
64
- itemsMarker: "[f1" + suffix
74
+ emptyMarker: HYDRATION_FOR_EMPTY + suffix,
75
+ itemsMarker: HYDRATION_FOR_ITEMS + suffix
65
76
  };
66
77
  }
67
78
  enclosingEnd = end;
@@ -1,6 +1,12 @@
1
1
  import { bumpContextEpoch } from "./context-epoch.js";
2
2
  import { isContext } from "./context-identity.js";
3
3
  import { hasOwnProp } from "./has-own.js";
4
+ import {
5
+ ACTIVITY_TAG,
6
+ CONTEXT_TAG,
7
+ LAZY_COMPONENT_TAG as LAZY_COMPONENT,
8
+ RENDERER_REGION_OWNER_TAG as RENDERER_REGION_OWNER
9
+ } from "./runtime-tags.js";
4
10
  import { resolveHookPath } from "./hook-slot-cache.js";
5
11
  import {
6
12
  __profileBeginRender,
@@ -40,8 +46,6 @@ const UNIVERSAL_ACTIVITY = /* @__PURE__ */ Symbol.for("octane.universal.activity
40
46
  const UNIVERSAL_KEYED = /* @__PURE__ */ Symbol.for("octane.universal.keyed");
41
47
  const UNIVERSAL_PORTAL = /* @__PURE__ */ Symbol.for("octane.universal.portal");
42
48
  const UNIVERSAL_RENDERER_REGION = /* @__PURE__ */ Symbol.for("octane.universal.renderer-region");
43
- const RENDERER_REGION_OWNER = /* @__PURE__ */ Symbol.for("octane.renderer-region.owner");
44
- const LAZY_COMPONENT = /* @__PURE__ */ Symbol.for("octane.lazy");
45
49
  const UNIVERSAL_COMPONENT_REVISION = /* @__PURE__ */ Symbol("octane.universal.component-revision");
46
50
  const NO_CHILDREN = /* @__PURE__ */ Symbol("octane.universal.no-children");
47
51
  const NO_KEY = /* @__PURE__ */ Symbol("octane.universal.no-key");
@@ -4112,7 +4116,7 @@ function lazy(load) {
4112
4116
  }
4113
4117
  function use(usable) {
4114
4118
  currentDraftOwner();
4115
- if (usable?.$$kind === /* @__PURE__ */ Symbol.for("octane.context")) {
4119
+ if (usable?.$$kind === CONTEXT_TAG) {
4116
4120
  return useContext(usable);
4117
4121
  }
4118
4122
  const thenable = usable;
@@ -4309,7 +4313,7 @@ function memo(component, compare) {
4309
4313
  function createPortal(children, target) {
4310
4314
  return Object.freeze({ $$kind: UNIVERSAL_PORTAL, children, target });
4311
4315
  }
4312
- const Activity = /* @__PURE__ */ Symbol.for("octane.Activity");
4316
+ const Activity = ACTIVITY_TAG;
4313
4317
  function runEffectCreate(hook) {
4314
4318
  const cleanup = hook.create(
4315
4319
  ...hook.deps ?? []
@@ -7,8 +7,8 @@ import {
7
7
  universalContext
8
8
  } from "./universal-core.js";
9
9
  import { registerRendererContext, renderRendererContextProvider } from "./renderer-bridge.js";
10
+ import { CONTEXT_TAG } from "./runtime-tags.js";
10
11
  import { registerContext } from "./context-identity.js";
11
- const CONTEXT_TAG = /* @__PURE__ */ Symbol.for("octane.context");
12
12
  // @__NO_SIDE_EFFECTS__
13
13
  function createContext(defaultValue) {
14
14
  const context = ((props, scope) => scope === void 0 ? universalContext(context, props.value, props.children) : renderRendererContextProvider(context, props, scope));
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "0.3.1";
1
+ const version = "0.3.2";
2
2
  export {
3
3
  version
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "octane",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -234,8 +234,8 @@
234
234
  "devDependencies": {
235
235
  "@tsrx/react": "^0.3.0",
236
236
  "@types/react-dom": "^19.2.3",
237
- "@wagmi/connectors": "8.0.25",
238
- "@wagmi/core": "3.6.4",
237
+ "@wagmi/connectors": "8.2.0",
238
+ "@wagmi/core": "3.6.5",
239
239
  "esbuild": "^0.28.1",
240
240
  "happy-dom": "^20.11.0",
241
241
  "playwright": "^1.61.1",