octane 0.1.9 → 0.1.10
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/compiler/compile.js +35 -16
- package/dist/compiler/slot-hooks.js +2 -2
- package/dist/hydration/event-capture.d.ts +30 -0
- package/dist/hydration/event-capture.js +152 -0
- package/dist/hydration/index.d.ts +1 -0
- package/dist/hydration/index.js +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -0
- package/dist/runtime.d.ts +7 -0
- package/dist/runtime.js +76 -142
- package/dist/runtime.server.d.ts +36 -0
- package/dist/runtime.server.js +115 -8
- package/dist/server/index.d.ts +1 -1
- package/package.json +2 -7
package/dist/compiler/compile.js
CHANGED
|
@@ -5051,7 +5051,7 @@ export function compile(source, filename, options) {
|
|
|
5051
5051
|
const args = [JSON.stringify(t.html)];
|
|
5052
5052
|
if (t.ns || t.frag) args.push(String(t.ns | 0));
|
|
5053
5053
|
if (t.frag) args.push(String(t.frag | 0));
|
|
5054
|
-
return `const ${t.name} = _$template(${args.join(', ')});`;
|
|
5054
|
+
return `const ${t.name} = /* @__PURE__ */ _$template(${args.join(', ')});`;
|
|
5055
5055
|
})
|
|
5056
5056
|
.join('\n');
|
|
5057
5057
|
const templatesBlock = templates ? templates + '\n\n' : '';
|
|
@@ -5131,18 +5131,18 @@ export function compile(source, filename, options) {
|
|
|
5131
5131
|
.join('\n') + '\n';
|
|
5132
5132
|
}
|
|
5133
5133
|
|
|
5134
|
-
// Cross-module singleRoot stamps (docs/comment-marker-elision-plan.md
|
|
5135
|
-
//
|
|
5136
|
-
//
|
|
5137
|
-
//
|
|
5138
|
-
// module tail so it lands on the final binding (incl. the hmr() wrapper —
|
|
5139
|
-
// the stamp goes on what importers see). Also feeds the runtime's existing
|
|
5134
|
+
// Cross-module singleRoot fallback stamps (docs/comment-marker-elision-plan.md
|
|
5135
|
+
// M1). Non-HMR initializers carry this metadata inside a tree-shakeable
|
|
5136
|
+
// binding; the tail remains for HMR wrappers and declaration shapes that cannot
|
|
5137
|
+
// safely move the source binding. Also feeds the runtime's existing
|
|
5140
5138
|
// value-position `$$singleRoot` descriptor check.
|
|
5141
5139
|
let stampBlock = '';
|
|
5142
5140
|
if (ctx.componentInfo) {
|
|
5143
5141
|
const stamps = [];
|
|
5144
5142
|
for (const [name, info] of ctx.componentInfo) {
|
|
5145
|
-
if (info.singleRoot === true
|
|
5143
|
+
if (info.singleRoot === true && info.singleRootInitialized !== true) {
|
|
5144
|
+
stamps.push(`${name}.$$singleRoot = true;`);
|
|
5145
|
+
}
|
|
5146
5146
|
}
|
|
5147
5147
|
for (const entry of ctx.devFunctionLocs) {
|
|
5148
5148
|
stamps.push(
|
|
@@ -7068,6 +7068,15 @@ function applyCssScoping(componentNode, ctx) {
|
|
|
7068
7068
|
return cssHash;
|
|
7069
7069
|
}
|
|
7070
7070
|
|
|
7071
|
+
// Attach definition metadata through the component's initializer rather than a
|
|
7072
|
+
// free-standing module mutation. The call-site annotation is valid because every
|
|
7073
|
+
// caller passes a freshly-created compiler function that cannot yet be observed;
|
|
7074
|
+
// bundlers may therefore discard the initializer together with an unused export.
|
|
7075
|
+
function singleRootInitializer(ctx, component) {
|
|
7076
|
+
ctx.runtimeNeeded.add('markSingleRoot');
|
|
7077
|
+
return `/* @__PURE__ */ _$markSingleRoot(${component})`;
|
|
7078
|
+
}
|
|
7079
|
+
|
|
7071
7080
|
function compileComponent(node, ctx, options) {
|
|
7072
7081
|
const name = node.id.name;
|
|
7073
7082
|
rejectAsyncOrGenerator(node, name);
|
|
@@ -7131,12 +7140,15 @@ function compileComponent(node, ctx, options) {
|
|
|
7131
7140
|
// module const) so the component's own body — where the function-
|
|
7132
7141
|
// expression name shadows the const — resolves `_$warmChild(Self, …)` to
|
|
7133
7142
|
// an object that carries the plan. hmr() forwards `__warm` from the
|
|
7134
|
-
// wrapped fn onto its wrapper for cross-module references.
|
|
7135
|
-
|
|
7143
|
+
// wrapped fn onto its wrapper for cross-module references. Both assignments
|
|
7144
|
+
// below target this freshly-emitted function, so unused initializers may drop.
|
|
7145
|
+
const warmedFn = ctx._pendingWarm
|
|
7146
|
+
? `/* @__PURE__ */ Object.assign(${fn}, { __warm: ${ctx._pendingWarm} })`
|
|
7147
|
+
: fn;
|
|
7136
7148
|
ctx._pendingWarm = null;
|
|
7137
7149
|
const abiFn =
|
|
7138
7150
|
hmrWrap && returnedOutput
|
|
7139
|
-
?
|
|
7151
|
+
? `/* @__PURE__ */ Object.assign(${warmedFn}, { __octaneReturnedOutput: true })`
|
|
7140
7152
|
: warmedFn;
|
|
7141
7153
|
|
|
7142
7154
|
// HMR-wrap exported components inline so the binding stays a `const` (no
|
|
@@ -7146,7 +7158,12 @@ function compileComponent(node, ctx, options) {
|
|
|
7146
7158
|
// function-name identity by NAMING the inner FunctionExpression — `hmr`
|
|
7147
7159
|
// returns a wrapper that delegates to whatever fn is currently committed,
|
|
7148
7160
|
// and `module.Foo[HMR].update(...)` swaps it on each accept.
|
|
7149
|
-
|
|
7161
|
+
let valueExpr = hmrWrap && isExported ? `_$hmr(${abiFn})` : abiFn;
|
|
7162
|
+
const componentInfo = ctx.componentInfo.get(name);
|
|
7163
|
+
if (!hmrWrap && componentInfo?.singleRoot === true) {
|
|
7164
|
+
valueExpr = singleRootInitializer(ctx, valueExpr);
|
|
7165
|
+
componentInfo.singleRootInitialized = true;
|
|
7166
|
+
}
|
|
7150
7167
|
const declaration = options && options.hmrMutable ? 'let' : 'const';
|
|
7151
7168
|
if (isDefault) {
|
|
7152
7169
|
if (options && options.hmrMutable) {
|
|
@@ -9794,13 +9811,15 @@ function lowerHostFragment(node, ctx, compInlinedSubs, parentNs = 'html', cssHas
|
|
|
9794
9811
|
// compileFunctionBody → emitElementHtml (via ctx._foldedDirectiveCalls).
|
|
9795
9812
|
body: { type: 'JSXCodeBlock', body: [], render: rendererEl, foldedDirectives: directiveCalls },
|
|
9796
9813
|
};
|
|
9797
|
-
|
|
9814
|
+
const renderer = compileFunctionBody(synthFn, ctx, fragName, parentNs, cssHash);
|
|
9798
9815
|
if ((node.type === 'Element' || node.type === 'JSXElement') && !isComponentTag(node)) {
|
|
9799
9816
|
// A host fragment is a SINGLE root element, so it can mount markerless (the
|
|
9800
9817
|
// element self-delimits) — matching `@{}`'s inline render exactly (no extra
|
|
9801
9818
|
// comment markers), which is required for byte-equal DOM when folding `@{}`.
|
|
9802
9819
|
// A returned JSX fragment may have multiple roots and must retain its range.
|
|
9803
|
-
ctx.hoistedHelpers.push(
|
|
9820
|
+
ctx.hoistedHelpers.push(`const ${fragName} = ${singleRootInitializer(ctx, renderer)};`);
|
|
9821
|
+
} else {
|
|
9822
|
+
ctx.hoistedHelpers.push(renderer);
|
|
9804
9823
|
}
|
|
9805
9824
|
ctx.runtimeNeeded.add('createElement');
|
|
9806
9825
|
return {
|
|
@@ -10123,7 +10142,7 @@ function allocHookSymbol(ctx, debugName, profile = null, forceSymbol = false) {
|
|
|
10123
10142
|
// and custom-hook boundaries retain the trailing-Symbol ABI consumed by
|
|
10124
10143
|
// published bindings. Both use the short, path-free description.
|
|
10125
10144
|
if (ctx._hookHash === undefined) ctx._hookHash = hookSlotHash(ctx.filename);
|
|
10126
|
-
symbolExpr =
|
|
10145
|
+
symbolExpr = `/* @__PURE__ */ Symbol(${JSON.stringify(`${ctx._hookHash}#${id}`)})`;
|
|
10127
10146
|
} else {
|
|
10128
10147
|
// Direct sites in a compiler-created render Scope only need a tiny local
|
|
10129
10148
|
// integer. Arbitrary callable helpers and custom-hook boundaries can share a
|
|
@@ -10132,7 +10151,7 @@ function allocHookSymbol(ctx, debugName, profile = null, forceSymbol = false) {
|
|
|
10132
10151
|
if (forceSymbol) {
|
|
10133
10152
|
const { baseName } = ensureHookSlotBase(ctx);
|
|
10134
10153
|
const numericExpr = id === 0 ? baseName : `${baseName} + ${id}`;
|
|
10135
|
-
symbolExpr =
|
|
10154
|
+
symbolExpr = `/* @__PURE__ */ Symbol(${numericExpr})`;
|
|
10136
10155
|
} else {
|
|
10137
10156
|
symbolExpr = String(id);
|
|
10138
10157
|
}
|
|
@@ -720,10 +720,10 @@ function allocHookSymbol(st, owner, local, imported, node) {
|
|
|
720
720
|
// Symbol() collapses those paths and collides state across call sites.
|
|
721
721
|
// Short filename hash + index; no module path in the output (see
|
|
722
722
|
// compile.js hookSlotHash for the full rationale).
|
|
723
|
-
symbolExpr =
|
|
723
|
+
symbolExpr = `/* @__PURE__ */ Symbol(${JSON.stringify(`${st.hash}#${id}`)})`;
|
|
724
724
|
} else {
|
|
725
725
|
const numericExpr = id === 0 ? st.slotBaseName : `${st.slotBaseName} + ${id}`;
|
|
726
|
-
symbolExpr =
|
|
726
|
+
symbolExpr = `/* @__PURE__ */ Symbol(${numericExpr})`;
|
|
727
727
|
}
|
|
728
728
|
if (st.profile) {
|
|
729
729
|
const componentId = `${st.profileFilename || '<anon>'}#${owner.name}@${owner.line}:${owner.column}`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const HYDRATE_SUPPORTED_INTERACTION_EVENTS: readonly ["auxclick", "click", "contextmenu", "dblclick", "focusin", "keydown", "keyup", "mousedown", "mouseenter", "mouseover", "mouseup", "pointerdown", "pointerenter", "pointerover", "pointerup"];
|
|
2
|
+
export interface HydrationReplayIntent {
|
|
3
|
+
event: Event;
|
|
4
|
+
path: number[];
|
|
5
|
+
}
|
|
6
|
+
export type HydrationIntentBoundaryStatus = 'hydrated' | 'never' | 'dormant' | 'handles';
|
|
7
|
+
export type HydrationIntentBoundary = (eventType: string, intent?: HydrationReplayIntent) => HydrationIntentBoundaryStatus;
|
|
8
|
+
/** @internal Resolve an event target to an element-only path beneath a marker. */
|
|
9
|
+
export declare function hydrationEventPathWithin(root: Element, target: EventTarget | null): number[] | null;
|
|
10
|
+
/**
|
|
11
|
+
* Install document-level capture for deferred-hydration interaction intent.
|
|
12
|
+
* Calling this function more than once for the same document is a no-op.
|
|
13
|
+
*
|
|
14
|
+
* Applications that can receive input before `hydrateRoot()` should call this
|
|
15
|
+
* from their lightweight client bootstrap. Mounting the first `<Hydrate>`
|
|
16
|
+
* boundary also invokes it as a synchronous fallback.
|
|
17
|
+
*/
|
|
18
|
+
export declare function initializeHydrationEventCapture(ownerDocument?: Document): void;
|
|
19
|
+
/** @internal Runtime bridge for a mounted deferred-hydration boundary. */
|
|
20
|
+
export declare function registerHydrationIntentBoundary(marker: Element, boundary: HydrationIntentBoundary): void;
|
|
21
|
+
/** @internal Runtime bridge for a removed deferred-hydration boundary. */
|
|
22
|
+
export declare function unregisterHydrationIntentBoundary(marker: Element, boundary: HydrationIntentBoundary): void;
|
|
23
|
+
/** @internal Consume intent captured before the runtime boundary was registered. */
|
|
24
|
+
export declare function takePendingHydrationIntents(marker: Element): HydrationReplayIntent[] | undefined;
|
|
25
|
+
/** @internal Consume conservative nested-dynamic intent recorded before registration. */
|
|
26
|
+
export declare function takeDelegatedDynamicHydrationIntent(marker: Element): boolean;
|
|
27
|
+
/** @internal Avoid duplicate handling by the boundary-local capture listener. */
|
|
28
|
+
export declare function wasEarlyHydrationIntentHandled(event: Event): boolean;
|
|
29
|
+
/** @internal Preserve nested dynamic intent discovered by a mounted parent. */
|
|
30
|
+
export declare function markDelegatedDynamicHydrationIntent(marker: Element): void;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HYDRATE_DEFAULT_INTERACTION_EVENTS,
|
|
3
|
+
HYDRATE_INTERACTION_EVENTS_ATTR
|
|
4
|
+
} from "./interaction-config.js";
|
|
5
|
+
const HYDRATE_MARKER_SELECTOR = "[data-octane-hydrate-id]";
|
|
6
|
+
const HYDRATE_WHEN_ATTR = "data-octane-hydrate-when";
|
|
7
|
+
function isHydrationNode(target) {
|
|
8
|
+
return target !== null && typeof target.nodeType === "number";
|
|
9
|
+
}
|
|
10
|
+
function isHydrationElement(target) {
|
|
11
|
+
return isHydrationNode(target) && target.nodeType === 1;
|
|
12
|
+
}
|
|
13
|
+
const HYDRATE_SUPPORTED_INTERACTION_EVENTS = [
|
|
14
|
+
"auxclick",
|
|
15
|
+
"click",
|
|
16
|
+
"contextmenu",
|
|
17
|
+
"dblclick",
|
|
18
|
+
"focusin",
|
|
19
|
+
"keydown",
|
|
20
|
+
"keyup",
|
|
21
|
+
"mousedown",
|
|
22
|
+
"mouseenter",
|
|
23
|
+
"mouseover",
|
|
24
|
+
"mouseup",
|
|
25
|
+
"pointerdown",
|
|
26
|
+
"pointerenter",
|
|
27
|
+
"pointerover",
|
|
28
|
+
"pointerup"
|
|
29
|
+
];
|
|
30
|
+
const HYDRATE_BOUNDARIES = /* @__PURE__ */ new WeakMap();
|
|
31
|
+
const HYDRATE_PENDING_INTENTS = /* @__PURE__ */ new WeakMap();
|
|
32
|
+
const HYDRATE_DELEGATED_DYNAMIC_MARKERS = /* @__PURE__ */ new WeakSet();
|
|
33
|
+
const HYDRATE_HANDLED_INTENT_EVENTS = /* @__PURE__ */ new WeakSet();
|
|
34
|
+
const HYDRATE_INTENT_DOCUMENTS = /* @__PURE__ */ new WeakSet();
|
|
35
|
+
function hydrationEventPathWithin(root, target) {
|
|
36
|
+
if (!isHydrationNode(target)) return null;
|
|
37
|
+
const path = [];
|
|
38
|
+
let node = isHydrationElement(target) ? target : target.parentElement;
|
|
39
|
+
while (node !== root) {
|
|
40
|
+
const parent = node?.parentElement ?? null;
|
|
41
|
+
if (parent === null) return null;
|
|
42
|
+
const index = Array.prototype.indexOf.call(parent.children, node);
|
|
43
|
+
if (index < 0) return null;
|
|
44
|
+
path.push(index);
|
|
45
|
+
node = parent;
|
|
46
|
+
}
|
|
47
|
+
path.reverse();
|
|
48
|
+
return path;
|
|
49
|
+
}
|
|
50
|
+
function markerStatus(marker, eventType) {
|
|
51
|
+
const boundary = HYDRATE_BOUNDARIES.get(marker);
|
|
52
|
+
if (boundary !== void 0) return boundary(eventType);
|
|
53
|
+
const when = marker.getAttribute(HYDRATE_WHEN_ATTR);
|
|
54
|
+
if (when === null) return "hydrated";
|
|
55
|
+
if (when === "never") return "never";
|
|
56
|
+
if (when === "dynamic") return eventType === "click" ? "handles" : "dormant";
|
|
57
|
+
if (when !== "interaction") return "dormant";
|
|
58
|
+
const custom = marker.getAttribute(HYDRATE_INTERACTION_EVENTS_ATTR);
|
|
59
|
+
const events = custom === null ? HYDRATE_DEFAULT_INTERACTION_EVENTS : custom.split(/\s+/).filter(Boolean);
|
|
60
|
+
return events.includes(eventType) ? "handles" : "dormant";
|
|
61
|
+
}
|
|
62
|
+
function handleEarlyHydrationIntent(event) {
|
|
63
|
+
const target = event.target;
|
|
64
|
+
if (!isHydrationElement(target)) return;
|
|
65
|
+
const markers = [];
|
|
66
|
+
let marker = target.closest(HYDRATE_MARKER_SELECTOR);
|
|
67
|
+
let matches = false;
|
|
68
|
+
while (marker !== null) {
|
|
69
|
+
markers.push(marker);
|
|
70
|
+
matches ||= markerStatus(marker, event.type) === "handles";
|
|
71
|
+
marker = marker.parentElement?.closest(HYDRATE_MARKER_SELECTOR) ?? null;
|
|
72
|
+
}
|
|
73
|
+
if (!matches || markers.length === 0) return;
|
|
74
|
+
markers.reverse();
|
|
75
|
+
let candidate = null;
|
|
76
|
+
let candidateBoundary;
|
|
77
|
+
for (let i = 0; i < markers.length; i++) {
|
|
78
|
+
const current = markers[i];
|
|
79
|
+
const status = markerStatus(current, event.type);
|
|
80
|
+
if (status === "hydrated") continue;
|
|
81
|
+
if (status === "never") return;
|
|
82
|
+
candidate = current;
|
|
83
|
+
candidateBoundary = HYDRATE_BOUNDARIES.get(current);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
if (candidate === null) return;
|
|
87
|
+
for (let i = 0; i < markers.length; i++) {
|
|
88
|
+
const current = markers[i];
|
|
89
|
+
if (current !== candidate && candidate.contains(current) && current.getAttribute(HYDRATE_WHEN_ATTR) === "dynamic" && !HYDRATE_BOUNDARIES.has(current)) {
|
|
90
|
+
HYDRATE_DELEGATED_DYNAMIC_MARKERS.add(current);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const path = hydrationEventPathWithin(candidate, event.target);
|
|
94
|
+
if (path === null) return;
|
|
95
|
+
const intent = { event, path };
|
|
96
|
+
HYDRATE_HANDLED_INTENT_EVENTS.add(event);
|
|
97
|
+
if (event.bubbles) {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
event.stopPropagation();
|
|
100
|
+
event.stopImmediatePropagation();
|
|
101
|
+
}
|
|
102
|
+
if (candidateBoundary !== void 0) {
|
|
103
|
+
candidateBoundary(event.type, intent);
|
|
104
|
+
} else {
|
|
105
|
+
const pending = HYDRATE_PENDING_INTENTS.get(candidate) ?? [];
|
|
106
|
+
pending.push(intent);
|
|
107
|
+
HYDRATE_PENDING_INTENTS.set(candidate, pending);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function initializeHydrationEventCapture(ownerDocument) {
|
|
111
|
+
const targetDocument = ownerDocument ?? (typeof document === "undefined" ? void 0 : document);
|
|
112
|
+
if (targetDocument === void 0 || HYDRATE_INTENT_DOCUMENTS.has(targetDocument)) return;
|
|
113
|
+
HYDRATE_INTENT_DOCUMENTS.add(targetDocument);
|
|
114
|
+
for (let i = 0; i < HYDRATE_SUPPORTED_INTERACTION_EVENTS.length; i++) {
|
|
115
|
+
targetDocument.addEventListener(
|
|
116
|
+
HYDRATE_SUPPORTED_INTERACTION_EVENTS[i],
|
|
117
|
+
handleEarlyHydrationIntent,
|
|
118
|
+
true
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function registerHydrationIntentBoundary(marker, boundary) {
|
|
123
|
+
HYDRATE_BOUNDARIES.set(marker, boundary);
|
|
124
|
+
}
|
|
125
|
+
function unregisterHydrationIntentBoundary(marker, boundary) {
|
|
126
|
+
if (HYDRATE_BOUNDARIES.get(marker) === boundary) HYDRATE_BOUNDARIES.delete(marker);
|
|
127
|
+
}
|
|
128
|
+
function takePendingHydrationIntents(marker) {
|
|
129
|
+
const intents = HYDRATE_PENDING_INTENTS.get(marker);
|
|
130
|
+
HYDRATE_PENDING_INTENTS.delete(marker);
|
|
131
|
+
return intents;
|
|
132
|
+
}
|
|
133
|
+
function takeDelegatedDynamicHydrationIntent(marker) {
|
|
134
|
+
return HYDRATE_DELEGATED_DYNAMIC_MARKERS.delete(marker);
|
|
135
|
+
}
|
|
136
|
+
function wasEarlyHydrationIntentHandled(event) {
|
|
137
|
+
return HYDRATE_HANDLED_INTENT_EVENTS.has(event);
|
|
138
|
+
}
|
|
139
|
+
function markDelegatedDynamicHydrationIntent(marker) {
|
|
140
|
+
HYDRATE_DELEGATED_DYNAMIC_MARKERS.add(marker);
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
HYDRATE_SUPPORTED_INTERACTION_EVENTS,
|
|
144
|
+
hydrationEventPathWithin,
|
|
145
|
+
initializeHydrationEventCapture,
|
|
146
|
+
markDelegatedDynamicHydrationIntent,
|
|
147
|
+
registerHydrationIntentBoundary,
|
|
148
|
+
takeDelegatedDynamicHydrationIntent,
|
|
149
|
+
takePendingHydrationIntents,
|
|
150
|
+
unregisterHydrationIntentBoundary,
|
|
151
|
+
wasEarlyHydrationIntentHandled
|
|
152
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { condition } from './condition.js';
|
|
2
2
|
export type { HydrationCondition } from './condition.js';
|
|
3
|
+
export { initializeHydrationEventCapture } from './event-capture.js';
|
|
3
4
|
export { idle } from './idle.js';
|
|
4
5
|
export type { IdleHydrationOptions } from './idle.js';
|
|
5
6
|
export { interaction } from './interaction.js';
|
package/dist/hydration/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { condition } from "./condition.js";
|
|
2
|
+
import { initializeHydrationEventCapture } from "./event-capture.js";
|
|
2
3
|
import { idle } from "./idle.js";
|
|
3
4
|
import { interaction } from "./interaction.js";
|
|
4
5
|
import { load } from "./load.js";
|
|
@@ -8,6 +9,7 @@ import { visible } from "./visible.js";
|
|
|
8
9
|
export {
|
|
9
10
|
condition,
|
|
10
11
|
idle,
|
|
12
|
+
initializeHydrationEventCapture,
|
|
11
13
|
interaction,
|
|
12
14
|
load,
|
|
13
15
|
media,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { version } from './version.js';
|
|
2
|
-
export {
|
|
2
|
+
export { initializeHydrationEventCapture } from './hydration/event-capture.js';
|
|
3
|
+
export { createRoot, hydrateRoot, flushSync, act, type Root, type RootOptions, useState, useReducer, useEffect, useLayoutEffect, useInsertionEffect, useMemo, useCallback, useRef, useId, useImperativeHandle, useEffectEvent, useSyncExternalStore, useDeferredValue, useTransition, useActionState, useFormStatus, useOptimistic, useDebugValue, type FormStatus, startTransition, requestFormReset, memo, lazy, preload, preinit, preconnect, prefetchDNS, createContext, use, useContext, type Context, type ForeignHostContext, Suspense, ErrorBoundary, Hydrate, Activity, ViewTransition, addTransitionType, ViewTransition as unstable_ViewTransition, addTransitionType as unstable_addTransitionType, ViewTransitionPseudoElement, type ViewTransitionProps, type ViewTransitionInstance, Fragment, createPortal, type PortalDescriptor, createElement, cloneElement, isValidElement, isChildrenBlock, Children, type ElementDescriptor, type ComponentBody, __useStateWithGetter, __useReducerWithGetter, __createVoidRoot, bindRendererRegionOwner, EXTERNAL_HYDRATION_PROMISE, HYDRATION_RANGE_BOUNDARY, createHostContextRequest, __vtSeen, template, clone, drainFrag, bag0, bag1, bag2, bag3, bag4, bag5, bag6, bag7, bag8, bag9, bag10, bag11, bag12, bag13, bag14, bag15, bag16, bagOf, evt0, evt0u, evt1, evt1u, evt2, evt2u, evtN, evtNu, htext, htextSwap, child, sibling, setText, setScriptText, setHTML, setDangerouslySetInnerHTML, setDangerouslySetInnerHTMLSources, markDangerouslySetInnerHTMLChildren, setAttribute, setStringData, setBooleanAttribute, setAriaAttribute, setClassName, setClassAttr, normalizeClass, setStyle, setSpread, snapshotSpread, setHostPropSources, queueNativeChangeDiagnostic, markNativeChangeDiagnosticStatic, setFormAction, setValue, setFormControlSources, setChecked, setCheckedCheckable, setSelectValue, setDefaultValue, setDefaultValueUncontrolled, setDefaultChecked, setAutoFocus, attachRef, queueRefAttach, queueRefDetach, injectStyle, headBlock, namespaceHead, namespaceHeadElement, delegateEvents, delegateCaptureEvents, forBlock, ifBlock, tryBlock, switchBlock, activityBlock, componentSlot, componentSlotVoid, componentSlotLite, compilerCacheContext, markSingleRoot, markChildrenBlock, childSlot, positionalChildren, textSlot, textHole, childTextHole, hostComponent, renderBlock, portal, hookSlots, withSlot, useBatch, warmMemo, warmChild, provideContext, mountFragmentRef, FragmentInstance, hmr, HMR, hasPendingWork, type Scope, type Block, drainPassiveEffects, setIsOctaneActEnvironment, setTransitionFallbackTimeout, getTransitionFallbackTimeout, } from './runtime.js';
|
|
3
4
|
export type { HydrateOptions, HydrateProps, HydrateWhen, HydrationInteractionEvent, HydrationInteractionEvents, HydrationPrefetchContext, HydrationPrefetchFunction, HydrationPrefetchStrategy, HydrationPrefetchWaitReason, HydrationStrategy, HydrationWhen, } from './hydration/types.js';
|
|
4
5
|
export { __serverRpc } from './server-rpc-client.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { version } from "./version.js";
|
|
2
|
+
import { initializeHydrationEventCapture } from "./hydration/event-capture.js";
|
|
2
3
|
import {
|
|
3
4
|
createRoot,
|
|
4
5
|
hydrateRoot,
|
|
@@ -137,6 +138,7 @@ import {
|
|
|
137
138
|
componentSlotVoid,
|
|
138
139
|
componentSlotLite,
|
|
139
140
|
compilerCacheContext,
|
|
141
|
+
markSingleRoot,
|
|
140
142
|
markChildrenBlock,
|
|
141
143
|
childSlot,
|
|
142
144
|
positionalChildren,
|
|
@@ -242,6 +244,7 @@ export {
|
|
|
242
244
|
htextSwap,
|
|
243
245
|
hydrateRoot,
|
|
244
246
|
ifBlock,
|
|
247
|
+
initializeHydrationEventCapture,
|
|
245
248
|
injectStyle,
|
|
246
249
|
isChildrenBlock,
|
|
247
250
|
isValidElement,
|
|
@@ -249,6 +252,7 @@ export {
|
|
|
249
252
|
markChildrenBlock,
|
|
250
253
|
markDangerouslySetInnerHTMLChildren,
|
|
251
254
|
markNativeChangeDiagnosticStatic,
|
|
255
|
+
markSingleRoot,
|
|
252
256
|
memo,
|
|
253
257
|
mountFragmentRef,
|
|
254
258
|
namespaceHead,
|
package/dist/runtime.d.ts
CHANGED
|
@@ -540,6 +540,13 @@ export declare function createContext<T>(defaultValue: T): Context<T>;
|
|
|
540
540
|
* propagation.)
|
|
541
541
|
*/
|
|
542
542
|
export declare function provideContext<T>(scope: Scope, context: Context<T>, value: T): void;
|
|
543
|
+
/**
|
|
544
|
+
* Compiler-emitted: attach markerless single-host-root metadata while a fresh
|
|
545
|
+
* component function is still being initialized. The compiler only calls this
|
|
546
|
+
* with an otherwise-unobserved function, so unused initializers are removable.
|
|
547
|
+
* @internal
|
|
548
|
+
*/
|
|
549
|
+
export declare function markSingleRoot<T extends Function>(component: T): T;
|
|
543
550
|
/**
|
|
544
551
|
* Compiler-emitted: tag a children-block render function so `isChildrenBlock` recognises it.
|
|
545
552
|
* Returns the function for inline use (`{ children: markChildrenBlock(__children$N) }`).
|
package/dist/runtime.js
CHANGED
|
@@ -39,6 +39,17 @@ import {
|
|
|
39
39
|
HYDRATE_DEFAULT_INTERACTION_EVENTS,
|
|
40
40
|
HYDRATE_INTERACTION_EVENTS_ATTR
|
|
41
41
|
} from "./hydration/interaction-config.js";
|
|
42
|
+
import {
|
|
43
|
+
HYDRATE_SUPPORTED_INTERACTION_EVENTS,
|
|
44
|
+
hydrationEventPathWithin,
|
|
45
|
+
initializeHydrationEventCapture,
|
|
46
|
+
markDelegatedDynamicHydrationIntent,
|
|
47
|
+
registerHydrationIntentBoundary,
|
|
48
|
+
takeDelegatedDynamicHydrationIntent,
|
|
49
|
+
takePendingHydrationIntents,
|
|
50
|
+
unregisterHydrationIntentBoundary,
|
|
51
|
+
wasEarlyHydrationIntentHandled
|
|
52
|
+
} from "./hydration/event-capture.js";
|
|
42
53
|
import { sanitizeURL, sanitizeURLAttribute } from "./sanitize-url.js";
|
|
43
54
|
import {
|
|
44
55
|
COMPONENT_FLAG_BOUNDARY,
|
|
@@ -1350,15 +1361,23 @@ function drainPostPaint() {
|
|
|
1350
1361
|
_postPaintCbs = [];
|
|
1351
1362
|
for (let i = 0; i < cbs.length; i++) cbs[i]();
|
|
1352
1363
|
}
|
|
1353
|
-
let _channel
|
|
1354
|
-
|
|
1355
|
-
_channel
|
|
1356
|
-
|
|
1364
|
+
let _channel;
|
|
1365
|
+
function initPostPaintChannel() {
|
|
1366
|
+
if (_channel === void 0) {
|
|
1367
|
+
if (typeof MessageChannel === "undefined") {
|
|
1368
|
+
_channel = null;
|
|
1369
|
+
} else {
|
|
1370
|
+
_channel = new MessageChannel();
|
|
1371
|
+
_channel.port1.onmessage = drainPostPaint;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return _channel;
|
|
1357
1375
|
}
|
|
1358
1376
|
function schedulePostPaint(cb) {
|
|
1359
1377
|
_postPaintCbs.push(cb);
|
|
1360
|
-
|
|
1361
|
-
|
|
1378
|
+
const channel = initPostPaintChannel();
|
|
1379
|
+
if (channel !== null) {
|
|
1380
|
+
requestAnimationFrame(() => channel.port2.postMessage(0));
|
|
1362
1381
|
} else {
|
|
1363
1382
|
requestAnimationFrame(() => setTimeout(drainPostPaint, 0));
|
|
1364
1383
|
}
|
|
@@ -2347,6 +2366,7 @@ function useEffectEvent(fn, slot) {
|
|
|
2347
2366
|
}
|
|
2348
2367
|
const CONTEXT_TAG = /* @__PURE__ */ Symbol.for("octane.context");
|
|
2349
2368
|
let COMPILER_CACHE_CONTEXT_EPOCH = 0;
|
|
2369
|
+
// @__NO_SIDE_EFFECTS__
|
|
2350
2370
|
function createContext(defaultValue) {
|
|
2351
2371
|
const ctx = function ProviderBody(props, scope) {
|
|
2352
2372
|
if (scope.$$ctxValues === null) scope.$$ctxValues = /* @__PURE__ */ new Map();
|
|
@@ -2374,6 +2394,10 @@ function provideContext(scope, context, value) {
|
|
|
2374
2394
|
scope.$$ctxValues.set(context, value);
|
|
2375
2395
|
}
|
|
2376
2396
|
const CHILDREN_BLOCK = /* @__PURE__ */ Symbol.for("octane.childrenBlock");
|
|
2397
|
+
function markSingleRoot(component) {
|
|
2398
|
+
component.$$singleRoot = true;
|
|
2399
|
+
return component;
|
|
2400
|
+
}
|
|
2377
2401
|
function markChildrenBlock(fn) {
|
|
2378
2402
|
if (typeof fn === "function") {
|
|
2379
2403
|
fn[CHILDREN_BLOCK] = true;
|
|
@@ -2392,23 +2416,6 @@ function childrenAsBody(children) {
|
|
|
2392
2416
|
const HYDRATE_ID_SLOT = /* @__PURE__ */ Symbol("octane.hydrate.id");
|
|
2393
2417
|
const HYDRATE_SETUP_SLOT = /* @__PURE__ */ Symbol("octane.hydrate.setup");
|
|
2394
2418
|
const HYDRATE_NOTIFY_SLOT = /* @__PURE__ */ Symbol("octane.hydrate.notify");
|
|
2395
|
-
const HYDRATE_SUPPORTED_INTERACTION_EVENTS = [
|
|
2396
|
-
"auxclick",
|
|
2397
|
-
"click",
|
|
2398
|
-
"contextmenu",
|
|
2399
|
-
"dblclick",
|
|
2400
|
-
"focusin",
|
|
2401
|
-
"keydown",
|
|
2402
|
-
"keyup",
|
|
2403
|
-
"mousedown",
|
|
2404
|
-
"mouseenter",
|
|
2405
|
-
"mouseover",
|
|
2406
|
-
"mouseup",
|
|
2407
|
-
"pointerdown",
|
|
2408
|
-
"pointerenter",
|
|
2409
|
-
"pointerover",
|
|
2410
|
-
"pointerup"
|
|
2411
|
-
];
|
|
2412
2419
|
const HYDRATE_STRATEGY_TYPES = /* @__PURE__ */ new Set([
|
|
2413
2420
|
"load",
|
|
2414
2421
|
"idle",
|
|
@@ -2420,11 +2427,6 @@ const HYDRATE_STRATEGY_TYPES = /* @__PURE__ */ new Set([
|
|
|
2420
2427
|
"dynamic"
|
|
2421
2428
|
]);
|
|
2422
2429
|
const HYDRATE_MARKER_SELECTOR = "[data-octane-hydrate-id]";
|
|
2423
|
-
const HYDRATE_DELEGATED_DYNAMIC_MARKERS = /* @__PURE__ */ new WeakSet();
|
|
2424
|
-
const HYDRATE_SLOTS_BY_MARKER = /* @__PURE__ */ new WeakMap();
|
|
2425
|
-
const HYDRATE_PENDING_INTENTS = /* @__PURE__ */ new WeakMap();
|
|
2426
|
-
const HYDRATE_HANDLED_INTENT_EVENTS = /* @__PURE__ */ new WeakSet();
|
|
2427
|
-
const HYDRATE_INTENT_DOCUMENTS = /* @__PURE__ */ new WeakSet();
|
|
2428
2430
|
function hydrateStrategyType(when) {
|
|
2429
2431
|
return typeof when === "function" ? "dynamic" : when?._t ?? "dynamic";
|
|
2430
2432
|
}
|
|
@@ -2608,22 +2610,7 @@ function teardownHydrateBoundary(state) {
|
|
|
2608
2610
|
cleanupHydrateInstallers(state);
|
|
2609
2611
|
state.prefetchAbort?.abort();
|
|
2610
2612
|
resolveHydrateWaiters(state, "abort");
|
|
2611
|
-
|
|
2612
|
-
}
|
|
2613
|
-
function eventPathWithin(root, target) {
|
|
2614
|
-
if (!(target instanceof Node)) return null;
|
|
2615
|
-
const path = [];
|
|
2616
|
-
let node = target instanceof Element ? target : target.parentElement;
|
|
2617
|
-
while (node !== root) {
|
|
2618
|
-
const parent = node?.parentElement ?? null;
|
|
2619
|
-
if (parent === null) return null;
|
|
2620
|
-
const index = Array.prototype.indexOf.call(parent.children, node);
|
|
2621
|
-
if (index < 0) return null;
|
|
2622
|
-
path.push(index);
|
|
2623
|
-
node = parent;
|
|
2624
|
-
}
|
|
2625
|
-
path.reverse();
|
|
2626
|
-
return path;
|
|
2613
|
+
unregisterHydrationIntentBoundary(state.wrapper, state.intentBoundary);
|
|
2627
2614
|
}
|
|
2628
2615
|
function resolveEventPath(root, path) {
|
|
2629
2616
|
let node = root;
|
|
@@ -2646,85 +2633,18 @@ function hydrateStrategyInteractionEvents(strategy) {
|
|
|
2646
2633
|
const custom = strategy._a?.()?.[HYDRATE_INTERACTION_EVENTS_ATTR];
|
|
2647
2634
|
return custom === void 0 ? HYDRATE_DEFAULT_INTERACTION_EVENTS : custom.split(/\s+/).filter(Boolean);
|
|
2648
2635
|
}
|
|
2649
|
-
function markerHandlesEarlyHydrationIntent(marker, eventType) {
|
|
2650
|
-
const state = HYDRATE_SLOTS_BY_MARKER.get(marker);
|
|
2651
|
-
if (state !== void 0) {
|
|
2652
|
-
return hydrateStrategyInteractionEvents(resolveHydrateStrategy(state))?.includes(eventType) ?? false;
|
|
2653
|
-
}
|
|
2654
|
-
const when = marker.getAttribute(HYDRATE_WHEN_ATTR);
|
|
2655
|
-
if (when === "dynamic") return eventType === "click";
|
|
2656
|
-
if (when !== "interaction") return false;
|
|
2657
|
-
const custom = marker.getAttribute(HYDRATE_INTERACTION_EVENTS_ATTR);
|
|
2658
|
-
const events = custom === null ? HYDRATE_DEFAULT_INTERACTION_EVENTS : custom.split(/\s+/).filter(Boolean);
|
|
2659
|
-
return events.includes(eventType);
|
|
2660
|
-
}
|
|
2661
2636
|
function queueHydrateIntent(state, intent) {
|
|
2662
2637
|
if (state.hydrated || resolveHydrateStrategy(state)._t === "never") return;
|
|
2663
2638
|
state.replays.push(intent);
|
|
2664
2639
|
requestHydrateBoundary(state);
|
|
2665
2640
|
}
|
|
2666
|
-
function
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
markers.push(marker);
|
|
2674
|
-
matches ||= markerHandlesEarlyHydrationIntent(marker, event.type);
|
|
2675
|
-
marker = marker.parentElement?.closest(HYDRATE_MARKER_SELECTOR) ?? null;
|
|
2676
|
-
}
|
|
2677
|
-
if (!matches || markers.length === 0) return;
|
|
2678
|
-
markers.reverse();
|
|
2679
|
-
let candidate = null;
|
|
2680
|
-
let candidateState;
|
|
2681
|
-
for (let i = 0; i < markers.length; i++) {
|
|
2682
|
-
const current = markers[i];
|
|
2683
|
-
const when = current.getAttribute(HYDRATE_WHEN_ATTR);
|
|
2684
|
-
if (when === null) continue;
|
|
2685
|
-
const state = HYDRATE_SLOTS_BY_MARKER.get(current);
|
|
2686
|
-
if (state?.hydrated) continue;
|
|
2687
|
-
if (when === "never" || state !== void 0 && resolveHydrateStrategy(state)._t === "never") {
|
|
2688
|
-
return;
|
|
2689
|
-
}
|
|
2690
|
-
candidate = current;
|
|
2691
|
-
candidateState = state;
|
|
2692
|
-
break;
|
|
2693
|
-
}
|
|
2694
|
-
if (candidate === null) return;
|
|
2695
|
-
for (let i = 0; i < markers.length; i++) {
|
|
2696
|
-
const current = markers[i];
|
|
2697
|
-
if (current !== candidate && candidate.contains(current) && current.getAttribute(HYDRATE_WHEN_ATTR) === "dynamic" && !HYDRATE_SLOTS_BY_MARKER.has(current)) {
|
|
2698
|
-
HYDRATE_DELEGATED_DYNAMIC_MARKERS.add(current);
|
|
2699
|
-
}
|
|
2700
|
-
}
|
|
2701
|
-
const path = eventPathWithin(candidate, event.target);
|
|
2702
|
-
if (path === null) return;
|
|
2703
|
-
const intent = { event, path };
|
|
2704
|
-
HYDRATE_HANDLED_INTENT_EVENTS.add(event);
|
|
2705
|
-
if (event.bubbles) {
|
|
2706
|
-
event.preventDefault();
|
|
2707
|
-
event.stopPropagation();
|
|
2708
|
-
event.stopImmediatePropagation();
|
|
2709
|
-
}
|
|
2710
|
-
if (candidateState !== void 0) {
|
|
2711
|
-
queueHydrateIntent(candidateState, intent);
|
|
2712
|
-
} else {
|
|
2713
|
-
const pending = HYDRATE_PENDING_INTENTS.get(candidate) ?? [];
|
|
2714
|
-
pending.push(intent);
|
|
2715
|
-
HYDRATE_PENDING_INTENTS.set(candidate, pending);
|
|
2716
|
-
}
|
|
2717
|
-
}
|
|
2718
|
-
function ensureEarlyHydrationIntentCapture(ownerDocument) {
|
|
2719
|
-
if (HYDRATE_INTENT_DOCUMENTS.has(ownerDocument)) return;
|
|
2720
|
-
HYDRATE_INTENT_DOCUMENTS.add(ownerDocument);
|
|
2721
|
-
for (let i = 0; i < HYDRATE_SUPPORTED_INTERACTION_EVENTS.length; i++) {
|
|
2722
|
-
ownerDocument.addEventListener(
|
|
2723
|
-
HYDRATE_SUPPORTED_INTERACTION_EVENTS[i],
|
|
2724
|
-
handleEarlyHydrationIntent,
|
|
2725
|
-
true
|
|
2726
|
-
);
|
|
2727
|
-
}
|
|
2641
|
+
function handleRegisteredHydrationIntent(state, eventType, intent) {
|
|
2642
|
+
if (state.hydrated) return "hydrated";
|
|
2643
|
+
const strategy = resolveHydrateStrategy(state);
|
|
2644
|
+
if (strategy._t === "never") return "never";
|
|
2645
|
+
const status = hydrateStrategyInteractionEvents(strategy)?.includes(eventType) ? "handles" : "dormant";
|
|
2646
|
+
if (intent !== void 0) queueHydrateIntent(state, intent);
|
|
2647
|
+
return status;
|
|
2728
2648
|
}
|
|
2729
2649
|
function installHydrateInteraction(state, strategy) {
|
|
2730
2650
|
const ownEvents = hydrateStrategyInteractionEvents(strategy) ?? // A parent-first replay may carry conservative intent for a dynamic marker
|
|
@@ -2740,7 +2660,7 @@ function installHydrateInteraction(state, strategy) {
|
|
|
2740
2660
|
}
|
|
2741
2661
|
if (events.size === 0) return () => void 0;
|
|
2742
2662
|
const onIntent = (event) => {
|
|
2743
|
-
if (
|
|
2663
|
+
if (wasEarlyHydrationIntentHandled(event)) return;
|
|
2744
2664
|
if (state.hydrated) return;
|
|
2745
2665
|
const rawTarget = event.target;
|
|
2746
2666
|
let target = rawTarget instanceof Element ? rawTarget : rawTarget instanceof Node ? rawTarget.parentElement : null;
|
|
@@ -2762,9 +2682,9 @@ function installHydrateInteraction(state, strategy) {
|
|
|
2762
2682
|
}
|
|
2763
2683
|
if (!matches) return;
|
|
2764
2684
|
for (let i = 0; i < delegatedDynamicMarkers.length; i++) {
|
|
2765
|
-
|
|
2685
|
+
markDelegatedDynamicHydrationIntent(delegatedDynamicMarkers[i]);
|
|
2766
2686
|
}
|
|
2767
|
-
const path =
|
|
2687
|
+
const path = hydrationEventPathWithin(state.wrapper, event.target);
|
|
2768
2688
|
if (path === null) return;
|
|
2769
2689
|
state.replays.push({ event, path });
|
|
2770
2690
|
if (event.bubbles) {
|
|
@@ -2859,7 +2779,7 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
2859
2779
|
const hydration = activeHydration();
|
|
2860
2780
|
const expected = document.createElement("div");
|
|
2861
2781
|
const wrapper = hydration === null ? expected : hydration.clone(expected);
|
|
2862
|
-
|
|
2782
|
+
initializeHydrationEventCapture(wrapper.ownerDocument);
|
|
2863
2783
|
let serverPreserved = hydration !== null && !hydration.isFresh(wrapper) && wrapper.parentNode === parentNode;
|
|
2864
2784
|
if (wrapper.parentNode !== parentNode) parentNode.insertBefore(wrapper, parentBlock.endMarker);
|
|
2865
2785
|
if (!wrapper.hasAttribute(HYDRATE_ID_ATTR)) wrapper.setAttribute(HYDRATE_ID_ATTR, boundaryId);
|
|
@@ -2909,7 +2829,9 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
2909
2829
|
void 0
|
|
2910
2830
|
);
|
|
2911
2831
|
block.idState = idState;
|
|
2912
|
-
|
|
2832
|
+
let state;
|
|
2833
|
+
const intentBoundary = (eventType, intent) => handleRegisteredHydrationIntent(state, eventType, intent);
|
|
2834
|
+
state = {
|
|
2913
2835
|
__kind: "hydrateBlockSlot",
|
|
2914
2836
|
__flags: SLOT_FLAG_TEARDOWN,
|
|
2915
2837
|
__teardown: teardownHydrateBoundary,
|
|
@@ -2920,7 +2842,8 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
2920
2842
|
parentBlock,
|
|
2921
2843
|
props,
|
|
2922
2844
|
boundaryId: wrapper.getAttribute(HYDRATE_ID_ATTR) ?? boundaryId,
|
|
2923
|
-
|
|
2845
|
+
intentBoundary,
|
|
2846
|
+
delegatedDynamicIntent: takeDelegatedDynamicHydrationIntent(wrapper),
|
|
2924
2847
|
serverPreserved,
|
|
2925
2848
|
preservedFallbackNodes: null,
|
|
2926
2849
|
seedRaw,
|
|
@@ -2948,11 +2871,10 @@ function createHydrateSlot(props, scope, boundaryId) {
|
|
|
2948
2871
|
};
|
|
2949
2872
|
scope.slots[0] = state;
|
|
2950
2873
|
registerSlot(scope, state);
|
|
2951
|
-
|
|
2874
|
+
registerHydrationIntentBoundary(wrapper, intentBoundary);
|
|
2952
2875
|
block.body = hydrateBoundaryBody(state);
|
|
2953
2876
|
const initialStrategy = resolveHydrateStrategy(state);
|
|
2954
|
-
const pendingIntents =
|
|
2955
|
-
HYDRATE_PENDING_INTENTS.delete(wrapper);
|
|
2877
|
+
const pendingIntents = takePendingHydrationIntents(wrapper);
|
|
2956
2878
|
if (serverPreserved && pendingIntents !== void 0 && initialStrategy._t !== "never") {
|
|
2957
2879
|
state.replays.push(...pendingIntents);
|
|
2958
2880
|
requestHydrateBoundary(state);
|
|
@@ -3018,7 +2940,6 @@ function notifyHydrateBoundary(state) {
|
|
|
3018
2940
|
}
|
|
3019
2941
|
}
|
|
3020
2942
|
function initializeHydrateComponent() {
|
|
3021
|
-
if (typeof document !== "undefined") ensureEarlyHydrationIntentCapture(document);
|
|
3022
2943
|
return markComponentFlags(
|
|
3023
2944
|
function Hydrate2(rawProps, scope) {
|
|
3024
2945
|
const props = rawProps;
|
|
@@ -3208,6 +3129,7 @@ function bindRendererRegionOwner(props) {
|
|
|
3208
3129
|
}
|
|
3209
3130
|
}
|
|
3210
3131
|
const HOST_CONTEXT_REQUEST_TAG = /* @__PURE__ */ Symbol.for("octane.host-context-request");
|
|
3132
|
+
// @__NO_SIDE_EFFECTS__
|
|
3211
3133
|
function createHostContextRequest(thenable) {
|
|
3212
3134
|
return { $$kind: HOST_CONTEXT_REQUEST_TAG, thenable };
|
|
3213
3135
|
}
|
|
@@ -3671,6 +3593,7 @@ function resolveLazyModule(mod) {
|
|
|
3671
3593
|
}
|
|
3672
3594
|
return comp;
|
|
3673
3595
|
}
|
|
3596
|
+
// @__NO_SIDE_EFFECTS__
|
|
3674
3597
|
function lazy(load) {
|
|
3675
3598
|
let status = "uninitialized";
|
|
3676
3599
|
let result = null;
|
|
@@ -3755,7 +3678,7 @@ function useId(slot) {
|
|
|
3755
3678
|
}
|
|
3756
3679
|
return s.id;
|
|
3757
3680
|
}
|
|
3758
|
-
const
|
|
3681
|
+
const LAZY_TEMPLATE = /* @__PURE__ */ Symbol("octane.lazy-template");
|
|
3759
3682
|
function parseTemplate(html, ns, frag) {
|
|
3760
3683
|
const t = document.createElement("template");
|
|
3761
3684
|
if (ns === 0) {
|
|
@@ -3775,13 +3698,16 @@ function parseTemplate(html, ns, frag) {
|
|
|
3775
3698
|
}
|
|
3776
3699
|
return wrapEl.firstChild;
|
|
3777
3700
|
}
|
|
3701
|
+
// @__NO_SIDE_EFFECTS__
|
|
3778
3702
|
function template(html, ns = 0, frag = 0) {
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3703
|
+
return {
|
|
3704
|
+
[LAZY_TEMPLATE]: {
|
|
3705
|
+
html,
|
|
3706
|
+
ns: ns === 1 ? 1 : ns === 2 ? 2 : ns === 3 ? 3 : 0,
|
|
3707
|
+
frag,
|
|
3708
|
+
parsed: []
|
|
3709
|
+
}
|
|
3710
|
+
};
|
|
3785
3711
|
}
|
|
3786
3712
|
let currentHydration = null;
|
|
3787
3713
|
function activeHydration() {
|
|
@@ -4211,14 +4137,19 @@ function parseSeedJson(raw) {
|
|
|
4211
4137
|
}
|
|
4212
4138
|
}
|
|
4213
4139
|
function clone(node, loc) {
|
|
4214
|
-
const
|
|
4215
|
-
if (
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4140
|
+
const lazy2 = node.nodeType === void 0 ? node[LAZY_TEMPLATE] : void 0;
|
|
4141
|
+
if (lazy2 !== void 0) {
|
|
4142
|
+
let ns;
|
|
4143
|
+
if (lazy2.ns === 3) {
|
|
4144
|
+
const inherited = CURRENT_SCOPE === null ? void 0 : deoptChildNamespace(CURRENT_SCOPE.block.parentNode);
|
|
4145
|
+
ns = inherited === SVG_NS ? 1 : inherited === MATHML_NS ? 2 : 0;
|
|
4146
|
+
} else {
|
|
4147
|
+
ns = lazy2.ns;
|
|
4148
|
+
}
|
|
4149
|
+
let parsed = lazy2.parsed[ns];
|
|
4219
4150
|
if (parsed === void 0) {
|
|
4220
|
-
parsed = parseTemplate(
|
|
4221
|
-
|
|
4151
|
+
parsed = parseTemplate(lazy2.html, ns, lazy2.frag);
|
|
4152
|
+
lazy2.parsed[ns] = parsed;
|
|
4222
4153
|
}
|
|
4223
4154
|
const hydration2 = activeHydration();
|
|
4224
4155
|
return hydration2 === null ? parsed.cloneNode(true) : hydration2.clone(parsed, loc);
|
|
@@ -6773,6 +6704,7 @@ function genericPortalBody(value, scope) {
|
|
|
6773
6704
|
childSlot(scope, 0, scope.parentNode, value, scope.endMarker);
|
|
6774
6705
|
}
|
|
6775
6706
|
const PORTAL_TAG = /* @__PURE__ */ Symbol.for("octane.portal");
|
|
6707
|
+
// @__NO_SIDE_EFFECTS__
|
|
6776
6708
|
function createPortal(body, target, props = void 0) {
|
|
6777
6709
|
return { $$kind: PORTAL_TAG, body, target, props };
|
|
6778
6710
|
}
|
|
@@ -8808,6 +8740,7 @@ function shallowEqualPropsExact(a, b) {
|
|
|
8808
8740
|
}
|
|
8809
8741
|
return true;
|
|
8810
8742
|
}
|
|
8743
|
+
// @__NO_SIDE_EFFECTS__
|
|
8811
8744
|
function memo(component, arePropsEqual) {
|
|
8812
8745
|
function memoWrapper(props, scope, extra) {
|
|
8813
8746
|
return component(props, scope, extra);
|
|
@@ -12118,6 +12051,7 @@ export {
|
|
|
12118
12051
|
markChildrenBlock,
|
|
12119
12052
|
markDangerouslySetInnerHTMLChildren,
|
|
12120
12053
|
markNativeChangeDiagnosticStatic,
|
|
12054
|
+
markSingleRoot,
|
|
12121
12055
|
memo,
|
|
12122
12056
|
mountFragmentRef,
|
|
12123
12057
|
namespaceHead,
|
package/dist/runtime.server.d.ts
CHANGED
|
@@ -605,10 +605,46 @@ export declare function renderToStaticMarkup(component: ServerComponent, props?:
|
|
|
605
605
|
* its pending form (content ships via its segment).
|
|
606
606
|
*/
|
|
607
607
|
export declare function ssrTry(scope: SSRScope, siteKey: string, tryFn: (arg: unknown, scope: SSRScope) => string, pendFn: ((arg: unknown, scope: SSRScope) => string) | null, catchFn: ((err: unknown, scope: SSRScope, reset: () => void) => string) | null, namespace?: 'html' | 'svg' | 'mathml', propagateSuspense?: boolean): string;
|
|
608
|
+
/**
|
|
609
|
+
* A live source of externally-produced HTML (typically framework data
|
|
610
|
+
* `<script>` tags materializing as loaders settle) merged natively into a
|
|
611
|
+
* streamed render. Octane emits injected HTML verbatim, in push order, each
|
|
612
|
+
* drain as its own transport chunk strictly BETWEEN renderer chunks — never
|
|
613
|
+
* before the shell, and (for document renders) before the held
|
|
614
|
+
* `</body></html>` tail. The stream stays open until `done` settles.
|
|
615
|
+
*
|
|
616
|
+
* This is an Octane extension (React's Fizz owns its data injection
|
|
617
|
+
* internally); it exists so frameworks like TanStack Start can merge their
|
|
618
|
+
* data stream without re-parsing the HTML byte stream for safe insertion
|
|
619
|
+
* points — every boundary between renderer chunks is tag-complete by
|
|
620
|
+
* construction.
|
|
621
|
+
*/
|
|
622
|
+
export interface StreamInjectionSource {
|
|
623
|
+
/**
|
|
624
|
+
* Pull all queued HTML (concatenated, verbatim). Called at emission
|
|
625
|
+
* boundaries and after `subscribe` notifications; return '' when empty.
|
|
626
|
+
*/
|
|
627
|
+
take(): string;
|
|
628
|
+
/**
|
|
629
|
+
* The source notifies when new HTML is queued; the renderer then drains
|
|
630
|
+
* promptly — even while the render itself is idle awaiting `done`.
|
|
631
|
+
* Returns an unsubscribe function; the renderer unsubscribes on
|
|
632
|
+
* completion, abort, and failure.
|
|
633
|
+
*/
|
|
634
|
+
subscribe(notify: () => void): () => void;
|
|
635
|
+
/**
|
|
636
|
+
* The renderer holds the document tail and the stream close until this
|
|
637
|
+
* settles. A rejection fails the stream through the fatal path (after the
|
|
638
|
+
* shell, mirroring abort: degraded terminal completion).
|
|
639
|
+
*/
|
|
640
|
+
done: Promise<void>;
|
|
641
|
+
}
|
|
608
642
|
export interface StreamOptions extends RenderOptions {
|
|
609
643
|
onShellReady?: () => void;
|
|
610
644
|
onShellError?: (err: unknown) => void;
|
|
611
645
|
onAllReady?: () => void;
|
|
646
|
+
/** Merge externally-produced HTML into the stream (see StreamInjectionSource). */
|
|
647
|
+
injection?: StreamInjectionSource;
|
|
612
648
|
}
|
|
613
649
|
/**
|
|
614
650
|
* React `react-dom/server` `renderToPipeableStream` (Node streams). Returns
|
package/dist/runtime.server.js
CHANGED
|
@@ -3283,6 +3283,12 @@ function withStream(stream, fn) {
|
|
|
3283
3283
|
STREAM = prev;
|
|
3284
3284
|
}
|
|
3285
3285
|
}
|
|
3286
|
+
const DOCUMENT_TAIL_RE = /^<\/body>(?:\s|<!--[^]*?-->)*<\/html>(?:\s|<!--[^]*?-->)*$/;
|
|
3287
|
+
function documentTailStart(body) {
|
|
3288
|
+
const index = body.lastIndexOf("</body>");
|
|
3289
|
+
if (index === -1) return -1;
|
|
3290
|
+
return DOCUMENT_TAIL_RE.test(body.slice(index)) ? index : -1;
|
|
3291
|
+
}
|
|
3286
3292
|
function segmentChunk(b, nonceAttr) {
|
|
3287
3293
|
let seedScript = "";
|
|
3288
3294
|
if (b.seeds.length > 0) {
|
|
@@ -3328,6 +3334,59 @@ async function runStream(component, props, options, sink) {
|
|
|
3328
3334
|
stream.activePassBoundaryKeys = previousBoundaryKeys;
|
|
3329
3335
|
}
|
|
3330
3336
|
};
|
|
3337
|
+
const injection = options?.injection;
|
|
3338
|
+
if (injection !== void 0) injection.done.then(NOOP, NOOP);
|
|
3339
|
+
let injectionUnsubscribe;
|
|
3340
|
+
let injectionFailure;
|
|
3341
|
+
let injectionFailed = false;
|
|
3342
|
+
let signalInjectionFailure;
|
|
3343
|
+
const failInjection = (err) => {
|
|
3344
|
+
if (injectionFailed) return;
|
|
3345
|
+
injectionFailed = true;
|
|
3346
|
+
injectionFailure = err;
|
|
3347
|
+
signalInjectionFailure?.();
|
|
3348
|
+
};
|
|
3349
|
+
let writeChain = injection === void 0 ? null : Promise.resolve();
|
|
3350
|
+
const write = injection === void 0 ? (chunk, terminal) => sink.write(chunk, terminal) : (chunk, terminal) => {
|
|
3351
|
+
const operation = writeChain.then(() => sink.write(chunk, terminal));
|
|
3352
|
+
writeChain = operation.then(NOOP, NOOP);
|
|
3353
|
+
return operation;
|
|
3354
|
+
};
|
|
3355
|
+
const drainInjection = () => {
|
|
3356
|
+
if (injection === void 0 || injectionFailed) return;
|
|
3357
|
+
let html;
|
|
3358
|
+
try {
|
|
3359
|
+
html = injection.take();
|
|
3360
|
+
} catch (err) {
|
|
3361
|
+
failInjection(err);
|
|
3362
|
+
return;
|
|
3363
|
+
}
|
|
3364
|
+
if (!html) return;
|
|
3365
|
+
return write(html);
|
|
3366
|
+
};
|
|
3367
|
+
const notifyInjection = () => {
|
|
3368
|
+
const drained = drainInjection();
|
|
3369
|
+
if (drained !== void 0) drained.catch(NOOP);
|
|
3370
|
+
};
|
|
3371
|
+
const waitForInjectionDone = () => new Promise((resolve, reject) => {
|
|
3372
|
+
let settled = false;
|
|
3373
|
+
const finish = (fn) => {
|
|
3374
|
+
if (settled) return;
|
|
3375
|
+
settled = true;
|
|
3376
|
+
signal?.removeEventListener("abort", onAbort);
|
|
3377
|
+
signalInjectionFailure = void 0;
|
|
3378
|
+
fn();
|
|
3379
|
+
};
|
|
3380
|
+
const onAbort = () => finish(() => reject(signal.reason));
|
|
3381
|
+
signalInjectionFailure = () => finish(() => reject(injectionFailure));
|
|
3382
|
+
if (injectionFailed) return finish(() => reject(injectionFailure));
|
|
3383
|
+
if (signal?.aborted) return onAbort();
|
|
3384
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
3385
|
+
injection.done.then(
|
|
3386
|
+
() => finish(resolve),
|
|
3387
|
+
(err) => finish(() => reject(err))
|
|
3388
|
+
);
|
|
3389
|
+
});
|
|
3331
3390
|
const emittedCss = /* @__PURE__ */ new Set();
|
|
3332
3391
|
const flushedSegments = /* @__PURE__ */ new Set();
|
|
3333
3392
|
const observedDone = /* @__PURE__ */ new Set();
|
|
@@ -3370,15 +3429,15 @@ async function runStream(component, props, options, sink) {
|
|
|
3370
3429
|
if (errors.length === 0) return;
|
|
3371
3430
|
let chunk = "";
|
|
3372
3431
|
for (const boundary of errors) chunk += boundaryErrorChunk(boundary, nonceAttr);
|
|
3373
|
-
const
|
|
3432
|
+
const errorWrite = write(chunk);
|
|
3374
3433
|
const markFlushed = () => {
|
|
3375
3434
|
for (const boundary of errors) boundary.errorFlushed = true;
|
|
3376
3435
|
};
|
|
3377
|
-
if (
|
|
3436
|
+
if (errorWrite === void 0) {
|
|
3378
3437
|
markFlushed();
|
|
3379
3438
|
return;
|
|
3380
3439
|
}
|
|
3381
|
-
return
|
|
3440
|
+
return errorWrite.then(markFlushed);
|
|
3382
3441
|
};
|
|
3383
3442
|
let pass;
|
|
3384
3443
|
let shellBoundaryKeys;
|
|
@@ -3416,13 +3475,24 @@ async function runStream(component, props, options, sink) {
|
|
|
3416
3475
|
emittedCss.add(hash);
|
|
3417
3476
|
shell += '<style data-octane="' + hash + '"' + nonceAttr + ">" + escapeEntireInlineStyleContent(sheet) + "</style>";
|
|
3418
3477
|
}
|
|
3419
|
-
|
|
3478
|
+
let heldDocumentTail = "";
|
|
3479
|
+
if (injection !== void 0) {
|
|
3480
|
+
const tailStart = documentTailStart(pass.body);
|
|
3481
|
+
if (tailStart !== -1) {
|
|
3482
|
+
heldDocumentTail = pass.body.slice(tailStart);
|
|
3483
|
+
shell += pass.head + pass.body.slice(0, tailStart);
|
|
3484
|
+
} else {
|
|
3485
|
+
shell += pass.head + pass.body;
|
|
3486
|
+
}
|
|
3487
|
+
} else {
|
|
3488
|
+
shell += pass.head + pass.body;
|
|
3489
|
+
}
|
|
3420
3490
|
if (pass.serial.length > 0) shell += serializeSuspenseSeeds(pass.serial, nonceAttr);
|
|
3421
3491
|
const anyPending = stream.boundaries.size > 0;
|
|
3422
3492
|
if (anyPending)
|
|
3423
3493
|
shell += "<script " + STREAM_SCRIPT_ATTR + nonceAttr + ">" + STREAM_RUNTIME_JS + "</script>";
|
|
3424
3494
|
try {
|
|
3425
|
-
const shellWrite =
|
|
3495
|
+
const shellWrite = write(pass.vtCandidates ? vtSsrStrip(shell) : shell);
|
|
3426
3496
|
if (shellWrite !== void 0) await shellWrite;
|
|
3427
3497
|
} catch (err) {
|
|
3428
3498
|
options?.onError?.(err);
|
|
@@ -3430,6 +3500,14 @@ async function runStream(component, props, options, sink) {
|
|
|
3430
3500
|
return;
|
|
3431
3501
|
}
|
|
3432
3502
|
sink.shellReady();
|
|
3503
|
+
if (injection !== void 0) {
|
|
3504
|
+
try {
|
|
3505
|
+
injectionUnsubscribe = injection.subscribe(notifyInjection);
|
|
3506
|
+
} catch (err) {
|
|
3507
|
+
failInjection(err);
|
|
3508
|
+
}
|
|
3509
|
+
notifyInjection();
|
|
3510
|
+
}
|
|
3433
3511
|
let suspended = pass.suspended;
|
|
3434
3512
|
let attempt = 0;
|
|
3435
3513
|
try {
|
|
@@ -3437,7 +3515,7 @@ async function runStream(component, props, options, sink) {
|
|
|
3437
3515
|
if (initiallyDone.length > 0) {
|
|
3438
3516
|
let chunk = "";
|
|
3439
3517
|
for (const boundary of initiallyDone) chunk += segmentChunk(boundary, nonceAttr);
|
|
3440
|
-
const segmentWrite =
|
|
3518
|
+
const segmentWrite = write(pass.vtCandidates ? vtSsrStrip(chunk) : chunk);
|
|
3441
3519
|
if (segmentWrite !== void 0) await segmentWrite;
|
|
3442
3520
|
for (const boundary of initiallyDone) {
|
|
3443
3521
|
flushedSegments.add(boundary.id);
|
|
@@ -3479,7 +3557,7 @@ async function runStream(component, props, options, sink) {
|
|
|
3479
3557
|
const done = reachableDoneSegments();
|
|
3480
3558
|
for (const b of done) chunk += segmentChunk(b, nonceAttr);
|
|
3481
3559
|
if (chunk !== "") {
|
|
3482
|
-
const segmentWrite =
|
|
3560
|
+
const segmentWrite = write(pass.vtCandidates ? vtSsrStrip(chunk) : chunk);
|
|
3483
3561
|
if (segmentWrite !== void 0) await segmentWrite;
|
|
3484
3562
|
for (const b of done) flushedSegments.add(b.id);
|
|
3485
3563
|
}
|
|
@@ -3496,16 +3574,45 @@ async function runStream(component, props, options, sink) {
|
|
|
3496
3574
|
for (const b of stream.boundaries.values()) {
|
|
3497
3575
|
if (!flushedSegments.has(b.id) && !b.errorFlushed) tail += boundaryErrorChunk(b, nonceAttr);
|
|
3498
3576
|
}
|
|
3577
|
+
if (heldDocumentTail !== "") tail += heldDocumentTail;
|
|
3499
3578
|
if (tail !== "") {
|
|
3500
3579
|
try {
|
|
3501
|
-
const terminalWrite =
|
|
3580
|
+
const terminalWrite = write(tail, true);
|
|
3502
3581
|
if (terminalWrite !== void 0) await terminalWrite;
|
|
3503
3582
|
} catch {
|
|
3504
3583
|
}
|
|
3505
3584
|
}
|
|
3585
|
+
injectionUnsubscribe?.();
|
|
3506
3586
|
sink.fatal(err);
|
|
3507
3587
|
return;
|
|
3508
3588
|
}
|
|
3589
|
+
if (injection !== void 0) {
|
|
3590
|
+
try {
|
|
3591
|
+
await waitForInjectionDone();
|
|
3592
|
+
const finalDrain = drainInjection();
|
|
3593
|
+
if (finalDrain !== void 0) await finalDrain;
|
|
3594
|
+
if (injectionFailed) throw injectionFailure;
|
|
3595
|
+
if (heldDocumentTail !== "") {
|
|
3596
|
+
const tailChunk = heldDocumentTail;
|
|
3597
|
+
heldDocumentTail = "";
|
|
3598
|
+
const tailWrite = write(tailChunk);
|
|
3599
|
+
if (tailWrite !== void 0) await tailWrite;
|
|
3600
|
+
}
|
|
3601
|
+
} catch (err) {
|
|
3602
|
+
options?.onError?.(err);
|
|
3603
|
+
if (heldDocumentTail !== "") {
|
|
3604
|
+
try {
|
|
3605
|
+
const terminalWrite = write(heldDocumentTail, true);
|
|
3606
|
+
if (terminalWrite !== void 0) await terminalWrite;
|
|
3607
|
+
} catch {
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
injectionUnsubscribe?.();
|
|
3611
|
+
sink.fatal(err);
|
|
3612
|
+
return;
|
|
3613
|
+
}
|
|
3614
|
+
injectionUnsubscribe?.();
|
|
3615
|
+
}
|
|
3509
3616
|
sink.allReady();
|
|
3510
3617
|
}
|
|
3511
3618
|
function renderToPipeableStream(component, props, options) {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -21,4 +21,4 @@
|
|
|
21
21
|
* should call them.
|
|
22
22
|
*/
|
|
23
23
|
export { executeServerFunction } from './rpc.js';
|
|
24
|
-
export { renderToString, renderToStaticMarkup, renderToPipeableStream, renderToReadableStream, type RenderResult, type RenderOptions, type StreamOptions, setSsrSuspenseTimeout, getSsrSuspenseTimeout, EXTERNAL_HYDRATION_PROMISE, HYDRATION_RANGE_BOUNDARY, useState, useReducer, __useStateWithGetter, __useReducerWithGetter, useEffect, useLayoutEffect, useInsertionEffect, useImperativeHandle, useMemo, useCallback, useRef, useId, useEffectEvent, useTransition, useDeferredValue, useSyncExternalStore, useActionState, useFormStatus, useOptimistic, useDebugValue, memo, lazy, hookSlots, withSlot, startTransition, flushSync, isChildrenBlock, isValidElement, cloneElement, Children, createPortal, requestFormReset, preload, preinit, preconnect, prefetchDNS, Suspense, ErrorBoundary, Hydrate, Fragment, Activity, ViewTransition, ViewTransition as unstable_ViewTransition, addTransitionType, addTransitionType as unstable_addTransitionType, createContext, use, useContext, ssrIsSuspense, type Context, type FormStatus, markChildrenBlock, createElement, positionalChildren, escapeHtml, escapeAttr, ssrText, ssrTextPre, ssrChild, ssrChildText, ssrAttr, normalizeClass, ssrStyle, ssrClass, ssrAttrs, ssrSnapshotSpread, ssrSpread, ssrInnerHtml, ssrScriptInnerHtml, ssrChildrenSources, ssrVoidContent, ssrValueAttr, ssrCheckedAttr, ssrInputAttrs, ssrTextareaValue, ssrTextareaValueSources, ssrSelectAttrs, ssrSelectScope, ssrSelectScopeSources, ssrOptionValueSources, ssrOption, ssrElement, ssrComponent, ssrComponentNS, ssrInNamespace, ssrBlock, ssrActivity, ssrForBlock, ssrControl, ssrArm, ssrTry, ssrPortal, injectStyle, ssrHeadEl, namespaceHead, namespaceHeadElement, puMemo, puBatch, warmMemo, warmChild, } from '../runtime.server.js';
|
|
24
|
+
export { renderToString, renderToStaticMarkup, renderToPipeableStream, renderToReadableStream, type RenderResult, type RenderOptions, type StreamOptions, type StreamInjectionSource, setSsrSuspenseTimeout, getSsrSuspenseTimeout, EXTERNAL_HYDRATION_PROMISE, HYDRATION_RANGE_BOUNDARY, useState, useReducer, __useStateWithGetter, __useReducerWithGetter, useEffect, useLayoutEffect, useInsertionEffect, useImperativeHandle, useMemo, useCallback, useRef, useId, useEffectEvent, useTransition, useDeferredValue, useSyncExternalStore, useActionState, useFormStatus, useOptimistic, useDebugValue, memo, lazy, hookSlots, withSlot, startTransition, flushSync, isChildrenBlock, isValidElement, cloneElement, Children, createPortal, requestFormReset, preload, preinit, preconnect, prefetchDNS, Suspense, ErrorBoundary, Hydrate, Fragment, Activity, ViewTransition, ViewTransition as unstable_ViewTransition, addTransitionType, addTransitionType as unstable_addTransitionType, createContext, use, useContext, ssrIsSuspense, type Context, type FormStatus, markChildrenBlock, createElement, positionalChildren, escapeHtml, escapeAttr, ssrText, ssrTextPre, ssrChild, ssrChildText, ssrAttr, normalizeClass, ssrStyle, ssrClass, ssrAttrs, ssrSnapshotSpread, ssrSpread, ssrInnerHtml, ssrScriptInnerHtml, ssrChildrenSources, ssrVoidContent, ssrValueAttr, ssrCheckedAttr, ssrInputAttrs, ssrTextareaValue, ssrTextareaValueSources, ssrSelectAttrs, ssrSelectScope, ssrSelectScopeSources, ssrOptionValueSources, ssrOption, ssrElement, ssrComponent, ssrComponentNS, ssrInNamespace, ssrBlock, ssrActivity, ssrForBlock, ssrControl, ssrArm, ssrTry, ssrPortal, injectStyle, ssrHeadEl, namespaceHead, namespaceHeadElement, puMemo, puBatch, warmMemo, warmChild, } from '../runtime.server.js';
|
package/package.json
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "octane",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"sideEffects":
|
|
7
|
-
"./src/index.ts",
|
|
8
|
-
"./src/runtime.ts",
|
|
9
|
-
"./dist/index.js",
|
|
10
|
-
"./dist/runtime.js"
|
|
11
|
-
],
|
|
6
|
+
"sideEffects": false,
|
|
12
7
|
"engines": {
|
|
13
8
|
"node": ">=22"
|
|
14
9
|
},
|