@ox-content/islands 3.1.2 → 3.1.4
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/html-host.cjs +8 -0
- package/dist/html-host.d.cts +88 -0
- package/dist/html-host.d.cts.map +1 -0
- package/dist/html-host.d.mts +88 -0
- package/dist/html-host.d.mts.map +1 -0
- package/dist/html-host.mjs +2 -0
- package/dist/html-host2.cjs +259 -0
- package/dist/html-host2.d.cts +2 -0
- package/dist/html-host2.d.mts +2 -0
- package/dist/html-host2.mjs +226 -0
- package/dist/html-host2.mjs.map +1 -0
- package/dist/index.cjs +15 -0
- package/dist/index.d.cts +19 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +4 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/runtime.cjs +5 -0
- package/dist/runtime.d.cts +95 -0
- package/dist/runtime.d.cts.map +1 -0
- package/dist/runtime.d.mts +2 -84
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime2.cjs +359 -0
- package/dist/runtime2.mjs +45 -19
- package/dist/runtime2.mjs.map +1 -1
- package/dist/types.d.cts +86 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +86 -0
- package/dist/types.d.mts.map +1 -0
- package/package.json +27 -5
- package/dist/runtime2.d.mts +0 -2
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
//#region src/html-host-errors.ts
|
|
2
|
+
var HtmlHostClientHydrationError = class extends Error {
|
|
3
|
+
diagnostic;
|
|
4
|
+
constructor(diagnostic) {
|
|
5
|
+
super(diagnostic.message);
|
|
6
|
+
this.name = "HtmlHostClientHydrationError";
|
|
7
|
+
this.diagnostic = diagnostic;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
function reportHtmlHostClientError(input, error, eventName = "ox-content-html-host:error") {
|
|
11
|
+
error.element.classList?.add("ox-island-error");
|
|
12
|
+
error.element.dataset.oxError = error.message;
|
|
13
|
+
input.onError?.(error);
|
|
14
|
+
if (typeof CustomEvent === "function" && typeof error.element.dispatchEvent === "function") error.element.dispatchEvent(new CustomEvent(eventName, { detail: error }));
|
|
15
|
+
}
|
|
16
|
+
function createHtmlHostClientError(code, element, props, context = {}) {
|
|
17
|
+
return {
|
|
18
|
+
code,
|
|
19
|
+
element,
|
|
20
|
+
props,
|
|
21
|
+
componentName: context.componentName,
|
|
22
|
+
moduleId: context.moduleId,
|
|
23
|
+
exportName: context.exportName,
|
|
24
|
+
cause: context.cause,
|
|
25
|
+
message: clientErrorMessage(code, context)
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function once(cleanup) {
|
|
29
|
+
let called = false;
|
|
30
|
+
return () => {
|
|
31
|
+
if (called) return;
|
|
32
|
+
called = true;
|
|
33
|
+
cleanup();
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function clientErrorMessage(code, context) {
|
|
37
|
+
const framework = context.frameworkName?.trim() || "HTML host";
|
|
38
|
+
const island = `${framework} island`;
|
|
39
|
+
const component = context.componentName ? `${island} "${context.componentName}"` : island;
|
|
40
|
+
const reason = causeMessage(context.cause);
|
|
41
|
+
switch (code) {
|
|
42
|
+
case "missing-island-name": return `${island} element is missing data-ox-island.`;
|
|
43
|
+
case "missing-module-id": return `${component} is missing data-ox-module.`;
|
|
44
|
+
case "unknown-module": return `${component} references unknown module "${context.moduleId ?? ""}".`;
|
|
45
|
+
case "module-load-failed": return `${component} module "${context.moduleId ?? ""}" failed to load: ${reason}`;
|
|
46
|
+
case "runtime-load-failed": return `${framework} runtime failed to load: ${reason}`;
|
|
47
|
+
case "missing-export": return `${component} module "${context.moduleId ?? ""}" is missing export "${context.exportName ?? "default"}".`;
|
|
48
|
+
case "render-failed": return `${component} failed to render: ${reason}`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function causeMessage(cause) {
|
|
52
|
+
if (cause == null) return "";
|
|
53
|
+
if (cause instanceof Error) return cause.message;
|
|
54
|
+
if (typeof cause === "string") return cause;
|
|
55
|
+
if (typeof cause === "number" || typeof cause === "boolean") return cause.toString();
|
|
56
|
+
try {
|
|
57
|
+
return JSON.stringify(cause);
|
|
58
|
+
} catch {
|
|
59
|
+
return Object.prototype.toString.call(cause);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/html-host.ts
|
|
64
|
+
const ISLAND_JSON_SCRIPT = /^\s*<script type="application\/json">[\s\S]*?<\/script>/;
|
|
65
|
+
function initHtmlHost(input) {
|
|
66
|
+
return input.initIslands(createHtmlHostLazyHydrate(input), input.options);
|
|
67
|
+
}
|
|
68
|
+
function createHtmlHostLazyHydrate(input) {
|
|
69
|
+
const render = resolveRenderer(input);
|
|
70
|
+
const loadRuntime = input.loadRuntime ?? input.adapter?.loadRuntime;
|
|
71
|
+
const preserveElementContents = input.preserveElementContents ?? input.adapter?.preserveElementContents ?? false;
|
|
72
|
+
const frameworkName = input.frameworkName ?? input.adapter?.frameworkName ?? "HTML host";
|
|
73
|
+
const eventName = input.eventName ?? input.adapter?.eventName ?? "ox-content-html-host:error";
|
|
74
|
+
const moduleCache = /* @__PURE__ */ new Map();
|
|
75
|
+
let runtimeCache;
|
|
76
|
+
return (element, props) => {
|
|
77
|
+
let disposed = false;
|
|
78
|
+
let disposeMounted;
|
|
79
|
+
const dispose = (() => {
|
|
80
|
+
if (disposed) return;
|
|
81
|
+
disposed = true;
|
|
82
|
+
disposeMounted?.();
|
|
83
|
+
disposeMounted = void 0;
|
|
84
|
+
});
|
|
85
|
+
const ready = (async () => {
|
|
86
|
+
const componentName = element.dataset.oxIsland;
|
|
87
|
+
if (!componentName) fail(input, eventName, frameworkName, "missing-island-name", element, props);
|
|
88
|
+
const moduleId = input.resolveModuleId?.(element, {
|
|
89
|
+
componentName,
|
|
90
|
+
props
|
|
91
|
+
}) ?? element.dataset.oxModule;
|
|
92
|
+
if (!moduleId) fail(input, eventName, frameworkName, "missing-module-id", element, props, { componentName });
|
|
93
|
+
if (!moduleLoader(input.modules, moduleId)) fail(input, eventName, frameworkName, "unknown-module", element, props, {
|
|
94
|
+
componentName,
|
|
95
|
+
moduleId
|
|
96
|
+
});
|
|
97
|
+
const exportName = input.resolveExportName?.(element, {
|
|
98
|
+
componentName,
|
|
99
|
+
moduleId,
|
|
100
|
+
props
|
|
101
|
+
}) ?? element.dataset.oxExport ?? "default";
|
|
102
|
+
const slotHtml = readHtmlHostSlot(element);
|
|
103
|
+
let moduleExports;
|
|
104
|
+
let runtime;
|
|
105
|
+
try {
|
|
106
|
+
moduleExports = await loadClientModule(input.modules, moduleId, moduleCache);
|
|
107
|
+
} catch (cause) {
|
|
108
|
+
if (!disposed) fail(input, eventName, frameworkName, "module-load-failed", element, props, {
|
|
109
|
+
componentName,
|
|
110
|
+
moduleId,
|
|
111
|
+
exportName,
|
|
112
|
+
cause
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (disposed) return;
|
|
117
|
+
try {
|
|
118
|
+
runtime = await loadHtmlHostRuntime(loadRuntime, () => runtimeCache, (pending) => {
|
|
119
|
+
runtimeCache = pending;
|
|
120
|
+
});
|
|
121
|
+
} catch (cause) {
|
|
122
|
+
if (!disposed) fail(input, eventName, frameworkName, "runtime-load-failed", element, props, {
|
|
123
|
+
componentName,
|
|
124
|
+
moduleId,
|
|
125
|
+
exportName,
|
|
126
|
+
cause
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (disposed) return;
|
|
131
|
+
const component = exportedValue(moduleExports, exportName);
|
|
132
|
+
if (component == null) fail(input, eventName, frameworkName, "missing-export", element, props, {
|
|
133
|
+
componentName,
|
|
134
|
+
moduleId,
|
|
135
|
+
exportName,
|
|
136
|
+
cause: /* @__PURE__ */ new Error(`Export "${exportName}" was not found.`)
|
|
137
|
+
});
|
|
138
|
+
if (!preserveElementContents) element.innerHTML = "";
|
|
139
|
+
try {
|
|
140
|
+
const cleanup = await render({
|
|
141
|
+
component,
|
|
142
|
+
componentName,
|
|
143
|
+
element,
|
|
144
|
+
exportName,
|
|
145
|
+
moduleExports,
|
|
146
|
+
moduleId,
|
|
147
|
+
props,
|
|
148
|
+
runtime,
|
|
149
|
+
slotHtml
|
|
150
|
+
});
|
|
151
|
+
disposeMounted = cleanup ? once(cleanup) : void 0;
|
|
152
|
+
if (disposed) {
|
|
153
|
+
disposeMounted?.();
|
|
154
|
+
disposeMounted = void 0;
|
|
155
|
+
}
|
|
156
|
+
} catch (cause) {
|
|
157
|
+
if (!disposed) fail(input, eventName, frameworkName, "render-failed", element, props, {
|
|
158
|
+
componentName,
|
|
159
|
+
moduleId,
|
|
160
|
+
exportName,
|
|
161
|
+
cause
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
})();
|
|
165
|
+
ready.catch(() => void 0);
|
|
166
|
+
Object.defineProperty(dispose, "then", { value: ready.then.bind(ready) });
|
|
167
|
+
return dispose;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function readHtmlHostSlot(element) {
|
|
171
|
+
const fromAttr = element.dataset.oxContent;
|
|
172
|
+
if (fromAttr) return fromAttr;
|
|
173
|
+
if (element.dataset.oxSsr === "true") return void 0;
|
|
174
|
+
return element.innerHTML.replace(ISLAND_JSON_SCRIPT, "") || void 0;
|
|
175
|
+
}
|
|
176
|
+
async function loadClientModule(modules, moduleId, cache) {
|
|
177
|
+
const cached = cache.get(moduleId);
|
|
178
|
+
if (cached) return cached;
|
|
179
|
+
const loader = moduleLoader(modules, moduleId);
|
|
180
|
+
if (!loader) throw new Error(`Unknown module "${moduleId}".`);
|
|
181
|
+
const pending = Promise.resolve().then(loader).catch((cause) => {
|
|
182
|
+
cache.delete(moduleId);
|
|
183
|
+
throw cause;
|
|
184
|
+
});
|
|
185
|
+
cache.set(moduleId, pending);
|
|
186
|
+
return pending;
|
|
187
|
+
}
|
|
188
|
+
async function loadHtmlHostRuntime(load, getCached, setCached) {
|
|
189
|
+
if (!load) return void 0;
|
|
190
|
+
const cached = getCached();
|
|
191
|
+
if (cached) return cached;
|
|
192
|
+
const pending = Promise.resolve().then(load).catch((cause) => {
|
|
193
|
+
setCached(void 0);
|
|
194
|
+
throw cause;
|
|
195
|
+
});
|
|
196
|
+
setCached(pending);
|
|
197
|
+
return pending;
|
|
198
|
+
}
|
|
199
|
+
function fail(input, eventName, frameworkName, code, element, props, context = {}) {
|
|
200
|
+
const error = createHtmlHostClientError(code, element, props, {
|
|
201
|
+
...context,
|
|
202
|
+
frameworkName
|
|
203
|
+
});
|
|
204
|
+
reportHtmlHostClientError(input, error, eventName);
|
|
205
|
+
throw new HtmlHostClientHydrationError(error);
|
|
206
|
+
}
|
|
207
|
+
function resolveRenderer(input) {
|
|
208
|
+
const render = input.render ?? input.adapter?.render;
|
|
209
|
+
if (render) return render;
|
|
210
|
+
throw new Error("initHtmlHost requires either render or adapter.render.");
|
|
211
|
+
}
|
|
212
|
+
function moduleLoader(modules, moduleId) {
|
|
213
|
+
return isReadonlyMap(modules) ? modules.get(moduleId) : modules[moduleId];
|
|
214
|
+
}
|
|
215
|
+
function isReadonlyMap(value) {
|
|
216
|
+
return typeof value.get === "function";
|
|
217
|
+
}
|
|
218
|
+
function exportedValue(moduleExports, exportName) {
|
|
219
|
+
if (exportName === "default" && typeof moduleExports === "function") return moduleExports;
|
|
220
|
+
if (!moduleExports || typeof moduleExports !== "object") return;
|
|
221
|
+
return moduleExports[exportName];
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { createHtmlHostClientError as a, HtmlHostClientHydrationError as i, initHtmlHost as n, reportHtmlHostClientError as o, readHtmlHostSlot as r, createHtmlHostLazyHydrate as t };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=html-host2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-host2.mjs","names":[],"sources":["../src/html-host-errors.ts","../src/html-host.ts"],"sourcesContent":["export type HtmlHostClientDiagnosticCode =\n | \"missing-island-name\"\n | \"missing-module-id\"\n | \"unknown-module\"\n | \"module-load-failed\"\n | \"runtime-load-failed\"\n | \"missing-export\"\n | \"render-failed\";\n\nexport interface HtmlHostClientError {\n code: HtmlHostClientDiagnosticCode;\n message: string;\n element: HTMLElement;\n props: Record<string, unknown>;\n componentName?: string;\n moduleId?: string;\n exportName?: string;\n cause?: unknown;\n}\n\nexport class HtmlHostClientHydrationError extends Error {\n readonly diagnostic: HtmlHostClientError;\n\n constructor(diagnostic: HtmlHostClientError) {\n super(diagnostic.message);\n this.name = \"HtmlHostClientHydrationError\";\n this.diagnostic = diagnostic;\n }\n}\n\ninterface HtmlHostClientErrorContext {\n componentName?: string;\n moduleId?: string;\n exportName?: string;\n cause?: unknown;\n frameworkName?: string;\n}\n\nexport function reportHtmlHostClientError(\n input: { onError?: (error: HtmlHostClientError) => void },\n error: HtmlHostClientError,\n eventName = \"ox-content-html-host:error\",\n): void {\n error.element.classList?.add(\"ox-island-error\");\n error.element.dataset.oxError = error.message;\n input.onError?.(error);\n\n if (typeof CustomEvent === \"function\" && typeof error.element.dispatchEvent === \"function\") {\n error.element.dispatchEvent(new CustomEvent(eventName, { detail: error }));\n }\n}\n\nexport function createHtmlHostClientError(\n code: HtmlHostClientDiagnosticCode,\n element: HTMLElement,\n props: Record<string, unknown>,\n context: HtmlHostClientErrorContext = {},\n): HtmlHostClientError {\n return {\n code,\n element,\n props,\n componentName: context.componentName,\n moduleId: context.moduleId,\n exportName: context.exportName,\n cause: context.cause,\n message: clientErrorMessage(code, context),\n };\n}\n\nexport function once(cleanup: () => void): () => void {\n let called = false;\n return () => {\n if (called) return;\n called = true;\n cleanup();\n };\n}\n\nfunction clientErrorMessage(\n code: HtmlHostClientDiagnosticCode,\n context: HtmlHostClientErrorContext,\n): string {\n const framework = context.frameworkName?.trim() || \"HTML host\";\n const island = `${framework} island`;\n const component = context.componentName ? `${island} \"${context.componentName}\"` : island;\n const reason = causeMessage(context.cause);\n switch (code) {\n case \"missing-island-name\":\n return `${island} element is missing data-ox-island.`;\n case \"missing-module-id\":\n return `${component} is missing data-ox-module.`;\n case \"unknown-module\":\n return `${component} references unknown module \"${context.moduleId ?? \"\"}\".`;\n case \"module-load-failed\":\n return `${component} module \"${context.moduleId ?? \"\"}\" failed to load: ${reason}`;\n case \"runtime-load-failed\":\n return `${framework} runtime failed to load: ${reason}`;\n case \"missing-export\":\n return `${component} module \"${context.moduleId ?? \"\"}\" is missing export \"${context.exportName ?? \"default\"}\".`;\n case \"render-failed\":\n return `${component} failed to render: ${reason}`;\n }\n}\n\nfunction causeMessage(cause: unknown): string {\n if (cause == null) return \"\";\n if (cause instanceof Error) return cause.message;\n if (typeof cause === \"string\") return cause;\n if (typeof cause === \"number\" || typeof cause === \"boolean\") return cause.toString();\n try {\n return JSON.stringify(cause);\n } catch {\n return Object.prototype.toString.call(cause);\n }\n}\n","import type { HydrateFunction, InitIslandsOptions } from \"./types\";\nimport {\n HtmlHostClientHydrationError,\n createHtmlHostClientError,\n once,\n reportHtmlHostClientError,\n type HtmlHostClientDiagnosticCode,\n type HtmlHostClientError,\n} from \"./html-host-errors\";\n\nconst ISLAND_JSON_SCRIPT = /^\\s*<script type=\"application\\/json\">[\\s\\S]*?<\\/script>/;\n\nexport { HtmlHostClientHydrationError, createHtmlHostClientError, reportHtmlHostClientError };\nexport type { HtmlHostClientDiagnosticCode, HtmlHostClientError };\n\nexport type HtmlHostClientComponentValue = unknown;\nexport type HtmlHostClientModuleValue = unknown;\n\nexport type HtmlHostClientModuleLoader<TModule = HtmlHostClientModuleValue> = () =>\n | TModule\n | PromiseLike<TModule>;\n\nexport type HtmlHostClientModules<TModule = HtmlHostClientModuleValue> =\n | Readonly<Record<string, HtmlHostClientModuleLoader<TModule>>>\n | ReadonlyMap<string, HtmlHostClientModuleLoader<TModule>>;\n\nexport interface HtmlHostClientContext<TRuntime = undefined> {\n component: unknown;\n componentName: string;\n element: HTMLElement;\n exportName: string;\n moduleExports: unknown;\n moduleId: string;\n props: Record<string, unknown>;\n runtime: TRuntime | undefined;\n slotHtml: string | undefined;\n}\n\nexport type HtmlHostClientRenderer<TRuntime = undefined> = (\n context: HtmlHostClientContext<TRuntime>,\n) => void | (() => void) | PromiseLike<void | (() => void)>;\n\nexport type HtmlHostClientRuntimeLoader<TRuntime = undefined> = () =>\n | TRuntime\n | PromiseLike<TRuntime>;\n\nexport type HtmlHostModuleIdResolver = (\n element: HTMLElement,\n context: { componentName: string; props: Record<string, unknown> },\n) => string | undefined;\n\nexport type HtmlHostExportNameResolver = (\n element: HTMLElement,\n context: { componentName: string; moduleId: string; props: Record<string, unknown> },\n) => string | undefined;\n\nexport interface HtmlHostClientAdapter<TRuntime = undefined> {\n frameworkName?: string;\n eventName?: string;\n render: HtmlHostClientRenderer<TRuntime>;\n loadRuntime?: HtmlHostClientRuntimeLoader<TRuntime>;\n preserveElementContents?: boolean;\n}\n\nexport interface CreateHtmlHostLazyHydrateInput<TRuntime = undefined> {\n modules: HtmlHostClientModules;\n adapter?: HtmlHostClientAdapter<TRuntime>;\n render?: HtmlHostClientRenderer<TRuntime>;\n loadRuntime?: HtmlHostClientRuntimeLoader<TRuntime>;\n preserveElementContents?: boolean;\n resolveModuleId?: HtmlHostModuleIdResolver;\n resolveExportName?: HtmlHostExportNameResolver;\n onError?: (error: HtmlHostClientError) => void;\n frameworkName?: string;\n eventName?: string;\n}\n\nexport type HtmlHostHydrationHandle = (() => void) & PromiseLike<void>;\n\nexport type HtmlHostLazyHydrateFunction = (\n element: HTMLElement,\n props: Record<string, unknown>,\n) => HtmlHostHydrationHandle;\n\nexport type HtmlHostInitIslands<TController = unknown> = (\n hydrate: HydrateFunction,\n options?: InitIslandsOptions,\n) => TController;\n\nexport type InitHtmlHostInput<TRuntime = undefined> = CreateHtmlHostLazyHydrateInput<TRuntime> & {\n initIslands: HtmlHostInitIslands;\n options?: InitIslandsOptions;\n};\n\nexport function initHtmlHost<TRuntime = undefined>(\n input: InitHtmlHostInput<TRuntime>,\n): ReturnType<InitHtmlHostInput<TRuntime>[\"initIslands\"]> {\n return input.initIslands(createHtmlHostLazyHydrate(input), input.options);\n}\n\nexport function createHtmlHostLazyHydrate<TRuntime = undefined>(\n input: CreateHtmlHostLazyHydrateInput<TRuntime>,\n): HtmlHostLazyHydrateFunction {\n const render = resolveRenderer(input);\n const loadRuntime = input.loadRuntime ?? input.adapter?.loadRuntime;\n const preserveElementContents =\n input.preserveElementContents ?? input.adapter?.preserveElementContents ?? false;\n const frameworkName = input.frameworkName ?? input.adapter?.frameworkName ?? \"HTML host\";\n const eventName = input.eventName ?? input.adapter?.eventName ?? \"ox-content-html-host:error\";\n const moduleCache = new Map<string, Promise<unknown>>();\n let runtimeCache: Promise<TRuntime> | undefined;\n\n return (element, props) => {\n let disposed = false;\n let disposeMounted: (() => void) | undefined;\n\n const dispose = (() => {\n if (disposed) return;\n disposed = true;\n disposeMounted?.();\n disposeMounted = undefined;\n }) as HtmlHostHydrationHandle;\n\n const ready = (async () => {\n const componentName = element.dataset.oxIsland;\n if (!componentName) {\n fail(input, eventName, frameworkName, \"missing-island-name\", element, props);\n }\n\n const moduleId =\n input.resolveModuleId?.(element, { componentName, props }) ?? element.dataset.oxModule;\n if (!moduleId) {\n fail(input, eventName, frameworkName, \"missing-module-id\", element, props, {\n componentName,\n });\n }\n if (!moduleLoader(input.modules, moduleId)) {\n fail(input, eventName, frameworkName, \"unknown-module\", element, props, {\n componentName,\n moduleId,\n });\n }\n\n const exportName =\n input.resolveExportName?.(element, { componentName, moduleId, props }) ??\n element.dataset.oxExport ??\n \"default\";\n const slotHtml = readHtmlHostSlot(element);\n\n let moduleExports: unknown;\n let runtime: TRuntime | undefined;\n try {\n moduleExports = await loadClientModule(input.modules, moduleId, moduleCache);\n } catch (cause) {\n if (!disposed) {\n fail(input, eventName, frameworkName, \"module-load-failed\", element, props, {\n componentName,\n moduleId,\n exportName,\n cause,\n });\n }\n return;\n }\n\n if (disposed) return;\n\n try {\n runtime = await loadHtmlHostRuntime(\n loadRuntime,\n () => runtimeCache,\n (pending) => {\n runtimeCache = pending;\n },\n );\n } catch (cause) {\n if (!disposed) {\n fail(input, eventName, frameworkName, \"runtime-load-failed\", element, props, {\n componentName,\n moduleId,\n exportName,\n cause,\n });\n }\n return;\n }\n\n if (disposed) return;\n\n const component = exportedValue(moduleExports, exportName);\n if (component == null) {\n fail(input, eventName, frameworkName, \"missing-export\", element, props, {\n componentName,\n moduleId,\n exportName,\n cause: new Error(`Export \"${exportName}\" was not found.`),\n });\n }\n\n if (!preserveElementContents) {\n element.innerHTML = \"\";\n }\n try {\n const cleanup = await render({\n component,\n componentName,\n element,\n exportName,\n moduleExports,\n moduleId,\n props,\n runtime,\n slotHtml,\n });\n disposeMounted = cleanup ? once(cleanup) : undefined;\n if (disposed) {\n disposeMounted?.();\n disposeMounted = undefined;\n }\n } catch (cause) {\n if (!disposed) {\n fail(input, eventName, frameworkName, \"render-failed\", element, props, {\n componentName,\n moduleId,\n exportName,\n cause,\n });\n }\n }\n })();\n\n ready.catch(() => undefined);\n // Promise-like handles let initIslands keep the loading state until async\n // module/runtime/render work has completed.\n // oxlint-disable-next-line unicorn/no-thenable\n Object.defineProperty(dispose, \"then\", { value: ready.then.bind(ready) });\n return dispose;\n };\n}\n\nexport function readHtmlHostSlot(\n element: Pick<HTMLElement, \"dataset\" | \"innerHTML\">,\n): string | undefined {\n const fromAttr = element.dataset.oxContent;\n if (fromAttr) return fromAttr;\n if (element.dataset.oxSsr === \"true\") return undefined;\n\n const slotHtml = element.innerHTML.replace(ISLAND_JSON_SCRIPT, \"\");\n return slotHtml || undefined;\n}\n\nasync function loadClientModule(\n modules: HtmlHostClientModules,\n moduleId: string,\n cache: Map<string, Promise<unknown>>,\n): Promise<unknown> {\n const cached = cache.get(moduleId);\n if (cached) return cached;\n\n const loader = moduleLoader(modules, moduleId);\n if (!loader) {\n throw new Error(`Unknown module \"${moduleId}\".`);\n }\n\n const pending = Promise.resolve()\n .then(loader)\n .catch((cause: unknown) => {\n cache.delete(moduleId);\n throw cause;\n });\n cache.set(moduleId, pending);\n return pending;\n}\n\nasync function loadHtmlHostRuntime<TRuntime>(\n load: HtmlHostClientRuntimeLoader<TRuntime> | undefined,\n getCached: () => Promise<TRuntime> | undefined,\n setCached: (pending: Promise<TRuntime> | undefined) => void,\n): Promise<TRuntime | undefined> {\n if (!load) return undefined;\n\n const cached = getCached();\n if (cached) return cached;\n\n const pending = Promise.resolve()\n .then(load)\n .catch((cause: unknown) => {\n setCached(undefined);\n throw cause;\n });\n setCached(pending);\n return pending;\n}\n\nfunction fail(\n input: Pick<CreateHtmlHostLazyHydrateInput, \"onError\">,\n eventName: string,\n frameworkName: string,\n code: HtmlHostClientDiagnosticCode,\n element: HTMLElement,\n props: Record<string, unknown>,\n context: {\n componentName?: string;\n moduleId?: string;\n exportName?: string;\n cause?: unknown;\n } = {},\n): never {\n const error = createHtmlHostClientError(code, element, props, {\n ...context,\n frameworkName,\n });\n reportHtmlHostClientError(input, error, eventName);\n throw new HtmlHostClientHydrationError(error);\n}\n\nfunction resolveRenderer<TRuntime>(\n input: CreateHtmlHostLazyHydrateInput<TRuntime>,\n): HtmlHostClientRenderer<TRuntime> {\n const render = input.render ?? input.adapter?.render;\n if (render) return render;\n throw new Error(\"initHtmlHost requires either render or adapter.render.\");\n}\n\nfunction moduleLoader(\n modules: HtmlHostClientModules,\n moduleId: string,\n): HtmlHostClientModuleLoader | undefined {\n return isReadonlyMap(modules) ? modules.get(moduleId) : modules[moduleId];\n}\n\nfunction isReadonlyMap(\n value: HtmlHostClientModules,\n): value is ReadonlyMap<string, HtmlHostClientModuleLoader> {\n return typeof (value as ReadonlyMap<string, HtmlHostClientModuleLoader>).get === \"function\";\n}\n\nfunction exportedValue(moduleExports: unknown, exportName: string): unknown {\n if (exportName === \"default\" && typeof moduleExports === \"function\") {\n return moduleExports;\n }\n if (!moduleExports || typeof moduleExports !== \"object\") {\n return undefined;\n }\n return (moduleExports as Record<string, unknown>)[exportName];\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("./runtime2.cjs");
|
|
3
|
+
const require_html_host = require("./html-host2.cjs");
|
|
4
|
+
exports.HtmlHostClientHydrationError = require_html_host.HtmlHostClientHydrationError;
|
|
5
|
+
exports.createDeferredInit = require_runtime.createDeferredInit;
|
|
6
|
+
exports.createHtmlHostClientError = require_html_host.createHtmlHostClientError;
|
|
7
|
+
exports.createHtmlHostLazyHydrate = require_html_host.createHtmlHostLazyHydrate;
|
|
8
|
+
exports.initHtmlHost = require_html_host.initHtmlHost;
|
|
9
|
+
exports.initIslands = require_runtime.initIslands;
|
|
10
|
+
exports.isIslandsSupported = require_runtime.isIslandsSupported;
|
|
11
|
+
exports.readHtmlHostSlot = require_html_host.readHtmlHostSlot;
|
|
12
|
+
exports.readIslandSlotHtml = require_runtime.readIslandSlotHtml;
|
|
13
|
+
exports.reportHtmlHostClientError = require_html_host.reportHtmlHostClientError;
|
|
14
|
+
exports.stripIslandPayloadScript = require_runtime.stripIslandPayloadScript;
|
|
15
|
+
exports.unwrapIslandProps = require_runtime.unwrapIslandProps;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { a as IslandController, i as IslandConfig, n as HydrateFunction, o as IslandInstance, r as InitIslandsOptions, s as LoadStrategy, t as ComponentRegistry } from "./types.cjs";
|
|
2
|
+
import { C as reportHtmlHostClientError, S as createHtmlHostClientError, _ as initHtmlHost, a as HtmlHostClientModuleLoader, b as HtmlHostClientError, c as HtmlHostClientRenderer, d as HtmlHostHydrationHandle, f as HtmlHostInitIslands, g as createHtmlHostLazyHydrate, h as InitHtmlHostInput, i as HtmlHostClientContext, l as HtmlHostClientRuntimeLoader, m as HtmlHostModuleIdResolver, n as HtmlHostClientAdapter, o as HtmlHostClientModuleValue, p as HtmlHostLazyHydrateFunction, r as HtmlHostClientComponentValue, s as HtmlHostClientModules, t as CreateHtmlHostLazyHydrateInput, u as HtmlHostExportNameResolver, v as readHtmlHostSlot, x as HtmlHostClientHydrationError, y as HtmlHostClientDiagnosticCode } from "./html-host.cjs";
|
|
3
|
+
import { createDeferredInit, initIslands, isIslandsSupported } from "./runtime.cjs";
|
|
4
|
+
//#region src/payload.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Flatten the Rust MDX island payload (`{ props, expressions, spreads }`)
|
|
7
|
+
* into the literal props object hydrate functions expect. Legacy flat
|
|
8
|
+
* `data-ox-props` objects from the Markdown regex path are returned as-is.
|
|
9
|
+
*/
|
|
10
|
+
declare function unwrapIslandProps(parsed: unknown): Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Slot markup for an island: `data-ox-content` when the regex path set it,
|
|
13
|
+
* otherwise inner HTML with the Rust JSON payload script stripped.
|
|
14
|
+
*/
|
|
15
|
+
declare function stripIslandPayloadScript(innerHTML: string): string;
|
|
16
|
+
declare function readIslandSlotHtml(element: Pick<HTMLElement, "dataset" | "innerHTML">): string;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { type ComponentRegistry, type CreateHtmlHostLazyHydrateInput, type HtmlHostClientAdapter, type HtmlHostClientComponentValue, type HtmlHostClientContext, type HtmlHostClientDiagnosticCode, type HtmlHostClientError, HtmlHostClientHydrationError, type HtmlHostClientModuleLoader, type HtmlHostClientModuleValue, type HtmlHostClientModules, type HtmlHostClientRenderer, type HtmlHostClientRuntimeLoader, type HtmlHostExportNameResolver, type HtmlHostHydrationHandle, type HtmlHostInitIslands, type HtmlHostLazyHydrateFunction, type HtmlHostModuleIdResolver, type HydrateFunction, type InitHtmlHostInput, type InitIslandsOptions, type IslandConfig, type IslandController, type IslandInstance, type LoadStrategy, createDeferredInit, createHtmlHostClientError, createHtmlHostLazyHydrate, initHtmlHost, initIslands, isIslandsSupported, readHtmlHostSlot, readIslandSlotHtml, reportHtmlHostClientError, stripIslandPayloadScript, unwrapIslandProps };
|
|
19
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/payload.ts"],"mappings":";;;;;;;;;iBAQgB,kBAAkB,kBAAkB;;;;;iBAwBpC,yBAAyB;iBAIzB,mBAAmB,SAAS,KAAK"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as IslandController, i as IslandConfig, n as HydrateFunction, o as IslandInstance, r as InitIslandsOptions, s as LoadStrategy, t as ComponentRegistry } from "./types.mjs";
|
|
2
|
+
import { C as reportHtmlHostClientError, S as createHtmlHostClientError, _ as initHtmlHost, a as HtmlHostClientModuleLoader, b as HtmlHostClientError, c as HtmlHostClientRenderer, d as HtmlHostHydrationHandle, f as HtmlHostInitIslands, g as createHtmlHostLazyHydrate, h as InitHtmlHostInput, i as HtmlHostClientContext, l as HtmlHostClientRuntimeLoader, m as HtmlHostModuleIdResolver, n as HtmlHostClientAdapter, o as HtmlHostClientModuleValue, p as HtmlHostLazyHydrateFunction, r as HtmlHostClientComponentValue, s as HtmlHostClientModules, t as CreateHtmlHostLazyHydrateInput, u as HtmlHostExportNameResolver, v as readHtmlHostSlot, x as HtmlHostClientHydrationError, y as HtmlHostClientDiagnosticCode } from "./html-host.mjs";
|
|
3
|
+
import { createDeferredInit, initIslands, isIslandsSupported } from "./runtime.mjs";
|
|
2
4
|
//#region src/payload.d.ts
|
|
3
5
|
/**
|
|
4
6
|
* Flatten the Rust MDX island payload (`{ props, expressions, spreads }`)
|
|
@@ -13,5 +15,5 @@ declare function unwrapIslandProps(parsed: unknown): Record<string, unknown>;
|
|
|
13
15
|
declare function stripIslandPayloadScript(innerHTML: string): string;
|
|
14
16
|
declare function readIslandSlotHtml(element: Pick<HTMLElement, "dataset" | "innerHTML">): string;
|
|
15
17
|
//#endregion
|
|
16
|
-
export { type ComponentRegistry, type HydrateFunction, type InitIslandsOptions, type IslandConfig, type IslandController, type IslandInstance, type LoadStrategy, createDeferredInit, initIslands, isIslandsSupported, readIslandSlotHtml, stripIslandPayloadScript, unwrapIslandProps };
|
|
18
|
+
export { type ComponentRegistry, type CreateHtmlHostLazyHydrateInput, type HtmlHostClientAdapter, type HtmlHostClientComponentValue, type HtmlHostClientContext, type HtmlHostClientDiagnosticCode, type HtmlHostClientError, HtmlHostClientHydrationError, type HtmlHostClientModuleLoader, type HtmlHostClientModuleValue, type HtmlHostClientModules, type HtmlHostClientRenderer, type HtmlHostClientRuntimeLoader, type HtmlHostExportNameResolver, type HtmlHostHydrationHandle, type HtmlHostInitIslands, type HtmlHostLazyHydrateFunction, type HtmlHostModuleIdResolver, type HydrateFunction, type InitHtmlHostInput, type InitIslandsOptions, type IslandConfig, type IslandController, type IslandInstance, type LoadStrategy, createDeferredInit, createHtmlHostClientError, createHtmlHostLazyHydrate, initHtmlHost, initIslands, isIslandsSupported, readHtmlHostSlot, readIslandSlotHtml, reportHtmlHostClientError, stripIslandPayloadScript, unwrapIslandProps };
|
|
17
19
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/payload.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/payload.ts"],"mappings":";;;;;;;;;iBAQgB,kBAAkB,kBAAkB;;;;;iBAwBpC,yBAAyB;iBAIzB,mBAAmB,SAAS,KAAK"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { a as stripIslandPayloadScript, i as readIslandSlotHtml, n as initIslands, o as unwrapIslandProps, r as isIslandsSupported, t as createDeferredInit } from "./runtime2.mjs";
|
|
2
|
-
|
|
2
|
+
import { a as createHtmlHostClientError, i as HtmlHostClientHydrationError, n as initHtmlHost, o as reportHtmlHostClientError, r as readHtmlHostSlot, t as createHtmlHostLazyHydrate } from "./html-host2.mjs";
|
|
3
|
+
export { HtmlHostClientHydrationError, createDeferredInit, createHtmlHostClientError, createHtmlHostLazyHydrate, initHtmlHost, initIslands, isIslandsSupported, readHtmlHostSlot, readIslandSlotHtml, reportHtmlHostClientError, stripIslandPayloadScript, unwrapIslandProps };
|
package/dist/runtime.cjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("./runtime2.cjs");
|
|
3
|
+
exports.createDeferredInit = require_runtime.createDeferredInit;
|
|
4
|
+
exports.initIslands = require_runtime.initIslands;
|
|
5
|
+
exports.isIslandsSupported = require_runtime.isIslandsSupported;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { a as IslandController, n as HydrateFunction, r as InitIslandsOptions } from "./types.cjs";
|
|
2
|
+
//#region src/runtime.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Initialize islands with a hydration function.
|
|
5
|
+
*
|
|
6
|
+
* This is the main entry point for the island system.
|
|
7
|
+
* Pass a hydrate function that knows how to mount your components.
|
|
8
|
+
*
|
|
9
|
+
* @example Vue
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { initIslands } from '@ox-content/islands';
|
|
12
|
+
* import { createApp, h } from 'vue';
|
|
13
|
+
* import Counter from './Counter.vue';
|
|
14
|
+
*
|
|
15
|
+
* const components = { Counter };
|
|
16
|
+
*
|
|
17
|
+
* initIslands((el, props) => {
|
|
18
|
+
* const name = el.dataset.oxIsland!;
|
|
19
|
+
* const Component = components[name];
|
|
20
|
+
* if (!Component) return;
|
|
21
|
+
*
|
|
22
|
+
* const app = createApp({ render: () => h(Component, props) });
|
|
23
|
+
* app.mount(el);
|
|
24
|
+
*
|
|
25
|
+
* return () => app.unmount();
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example React
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { initIslands } from '@ox-content/islands';
|
|
32
|
+
* import { createRoot } from 'react-dom/client';
|
|
33
|
+
* import Counter from './Counter';
|
|
34
|
+
*
|
|
35
|
+
* const components = { Counter };
|
|
36
|
+
*
|
|
37
|
+
* initIslands((el, props) => {
|
|
38
|
+
* const name = el.dataset.oxIsland!;
|
|
39
|
+
* const Component = components[name];
|
|
40
|
+
* if (!Component) return;
|
|
41
|
+
*
|
|
42
|
+
* const root = createRoot(el);
|
|
43
|
+
* root.render(<Component {...props} />);
|
|
44
|
+
*
|
|
45
|
+
* return () => root.unmount();
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example Vanilla JS
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { initIslands } from '@ox-content/islands';
|
|
52
|
+
*
|
|
53
|
+
* initIslands((el, props) => {
|
|
54
|
+
* const name = el.dataset.oxIsland!;
|
|
55
|
+
*
|
|
56
|
+
* if (name === 'Counter') {
|
|
57
|
+
* let count = props.initial || 0;
|
|
58
|
+
* const button = el.querySelector('button')!;
|
|
59
|
+
* const handler = () => {
|
|
60
|
+
* count++;
|
|
61
|
+
* button.textContent = String(count);
|
|
62
|
+
* };
|
|
63
|
+
* button.addEventListener('click', handler);
|
|
64
|
+
* return () => button.removeEventListener('click', handler);
|
|
65
|
+
* }
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare function initIslands(hydrate: HydrateFunction, options?: InitIslandsOptions): IslandController;
|
|
70
|
+
/**
|
|
71
|
+
* Create a deferred hydration wrapper.
|
|
72
|
+
*
|
|
73
|
+
* Returns a function that can be called to hydrate islands later.
|
|
74
|
+
* Useful for frameworks that need to register components first.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const deferredInit = createDeferredInit();
|
|
79
|
+
*
|
|
80
|
+
* // Later, after components are ready
|
|
81
|
+
* const components = await loadComponents();
|
|
82
|
+
* deferredInit((el, props) => {
|
|
83
|
+
* const Component = components[el.dataset.oxIsland!];
|
|
84
|
+
* // ...
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function createDeferredInit(options?: InitIslandsOptions): (hydrate: HydrateFunction) => IslandController;
|
|
89
|
+
/**
|
|
90
|
+
* Check if islands are supported in the current environment.
|
|
91
|
+
*/
|
|
92
|
+
declare function isIslandsSupported(): boolean;
|
|
93
|
+
//#endregion
|
|
94
|
+
export { createDeferredInit, initIslands, isIslandsSupported };
|
|
95
|
+
//# sourceMappingURL=runtime.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.cts","names":[],"sources":["../src/runtime.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwLgB,YACd,SAAS,iBACT,UAAU,qBACT;;;;;;;;;;;;;;;;;;;iBAqMa,mBACd,UAAU,sBACR,SAAS,oBAAoB;;;;iBAOjB"}
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,86 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Island Architecture Types
|
|
4
|
-
*
|
|
5
|
-
* Framework-agnostic type definitions for the Island system.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Loading strategy for islands.
|
|
9
|
-
*
|
|
10
|
-
* - `eager`: Hydrate immediately on page load
|
|
11
|
-
* - `idle`: Hydrate when the browser is idle (requestIdleCallback)
|
|
12
|
-
* - `visible`: Hydrate when the element becomes visible (IntersectionObserver)
|
|
13
|
-
* - `media`: Hydrate when a media query matches
|
|
14
|
-
*/
|
|
15
|
-
type LoadStrategy = "eager" | "idle" | "visible" | "media";
|
|
16
|
-
/**
|
|
17
|
-
* Island configuration extracted from data attributes.
|
|
18
|
-
*/
|
|
19
|
-
interface IslandConfig {
|
|
20
|
-
/** Unique island identifier */
|
|
21
|
-
id: string;
|
|
22
|
-
/** Component name to hydrate */
|
|
23
|
-
component: string;
|
|
24
|
-
/** Loading strategy */
|
|
25
|
-
load: LoadStrategy;
|
|
26
|
-
/** Media query for 'media' load strategy */
|
|
27
|
-
mediaQuery?: string;
|
|
28
|
-
/** Component props (JSON serialized in data-ox-props) */
|
|
29
|
-
props: Record<string, unknown>;
|
|
30
|
-
/** Whether the island wrapper already contains server-rendered component HTML. */
|
|
31
|
-
ssr?: boolean;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Hydration function signature.
|
|
35
|
-
*
|
|
36
|
-
* Called when an island should be hydrated.
|
|
37
|
-
* Returns an optional cleanup function.
|
|
38
|
-
*/
|
|
39
|
-
type HydrateFunction = (element: HTMLElement, props: Record<string, unknown>) => void | (() => void);
|
|
40
|
-
/**
|
|
41
|
-
* Component registry mapping component names to hydrate functions.
|
|
42
|
-
*/
|
|
43
|
-
type ComponentRegistry = Map<string, HydrateFunction>;
|
|
44
|
-
/**
|
|
45
|
-
* Options for initializing islands.
|
|
46
|
-
*/
|
|
47
|
-
interface InitIslandsOptions {
|
|
48
|
-
/** Root margin for IntersectionObserver (visible strategy). Default: "200px" */
|
|
49
|
-
rootMargin?: string;
|
|
50
|
-
/** Threshold for IntersectionObserver. Default: 0 */
|
|
51
|
-
threshold?: number;
|
|
52
|
-
/** Timeout for idle callback fallback in ms. Default: 200 */
|
|
53
|
-
idleTimeout?: number;
|
|
54
|
-
/** Custom selector for finding islands. Default: "[data-ox-island]" */
|
|
55
|
-
selector?: string;
|
|
56
|
-
/** Called when an island starts hydrating */
|
|
57
|
-
onHydrateStart?: (element: HTMLElement, config: IslandConfig) => void;
|
|
58
|
-
/** Called when an island finishes hydrating */
|
|
59
|
-
onHydrateEnd?: (element: HTMLElement, config: IslandConfig) => void;
|
|
60
|
-
/** Called when hydration fails */
|
|
61
|
-
onHydrateError?: (element: HTMLElement, config: IslandConfig, error: Error) => void;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Island instance tracking.
|
|
65
|
-
*/
|
|
66
|
-
interface IslandInstance {
|
|
67
|
-
element: HTMLElement;
|
|
68
|
-
config: IslandConfig;
|
|
69
|
-
cleanup?: () => void;
|
|
70
|
-
hydrated: boolean;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Island controller returned by initIslands.
|
|
74
|
-
*/
|
|
75
|
-
interface IslandController {
|
|
76
|
-
/** All tracked island instances */
|
|
77
|
-
instances: IslandInstance[];
|
|
78
|
-
/** Manually hydrate a specific island */
|
|
79
|
-
hydrate: (element: HTMLElement) => void;
|
|
80
|
-
/** Destroy all islands and cleanup */
|
|
81
|
-
destroy: () => void;
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
1
|
+
import { a as IslandController, n as HydrateFunction, r as InitIslandsOptions } from "./types.mjs";
|
|
84
2
|
//#region src/runtime.d.ts
|
|
85
3
|
/**
|
|
86
4
|
* Initialize islands with a hydration function.
|
|
@@ -173,5 +91,5 @@ declare function createDeferredInit(options?: InitIslandsOptions): (hydrate: Hyd
|
|
|
173
91
|
*/
|
|
174
92
|
declare function isIslandsSupported(): boolean;
|
|
175
93
|
//#endregion
|
|
176
|
-
export {
|
|
94
|
+
export { createDeferredInit, initIslands, isIslandsSupported };
|
|
177
95
|
//# sourceMappingURL=runtime.d.mts.map
|
package/dist/runtime.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/runtime.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwLgB,YACd,SAAS,iBACT,UAAU,qBACT;;;;;;;;;;;;;;;;;;;iBAqMa,mBACd,UAAU,sBACR,SAAS,oBAAoB;;;;iBAOjB"}
|