vite-plugin-shopify-theme-islands 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ import { type ReviveOptions } from "./contract.js";
2
+ import type { ClientDirectiveDefinition, DirectivesConfig, ShopifyThemeIslandsOptions } from "./options.js";
3
+ export interface ResolvedThemeIslandsPolicy {
4
+ plugin: {
5
+ directives: DirectivesConfig;
6
+ customDirectives: ClientDirectiveDefinition[];
7
+ debug: boolean;
8
+ };
9
+ runtime: ReviveOptions;
10
+ }
11
+ export declare function resolveThemeIslandsPolicy(options?: ShopifyThemeIslandsOptions): ResolvedThemeIslandsPolicy;
@@ -0,0 +1,27 @@
1
+ import type { ClientDirective, NormalizedReviveOptions } from "./contract.js";
2
+ import type { RuntimeLogger } from "./runtime-surface.js";
3
+ export interface DirectiveWaiters {
4
+ waitVisible(element: Element, rootMargin: string, threshold: number, watch: (el: Element, cancel: () => void) => () => void): Promise<void>;
5
+ waitMedia(query: string): Promise<void>;
6
+ waitIdle(timeout: number): Promise<void>;
7
+ waitDelay(ms: number): Promise<void>;
8
+ waitInteraction(element: Element, events: string[], watch: (el: Element, cancel: () => void) => () => void): Promise<void>;
9
+ }
10
+ export interface DirectiveRunContext {
11
+ tagName: string;
12
+ element: HTMLElement;
13
+ directives: NormalizedReviveOptions["directives"];
14
+ customDirectives?: Map<string, ClientDirective>;
15
+ directiveTimeout: number;
16
+ watchCancellable: (el: Element, cancel: () => void) => () => void;
17
+ log: RuntimeLogger;
18
+ run: () => Promise<void>;
19
+ onError(attrName: string, err: unknown): void;
20
+ }
21
+ export interface DirectiveOrchestrator {
22
+ run(ctx: DirectiveRunContext): Promise<boolean>;
23
+ }
24
+ export declare class DirectiveCancelledError extends Error {
25
+ constructor();
26
+ }
27
+ export declare function createDirectiveOrchestrator(waiters?: DirectiveWaiters): DirectiveOrchestrator;
package/dist/events.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { IslandLoadDetail, IslandErrorDetail } from "./index.js";
1
+ import type { IslandLoadDetail, IslandErrorDetail } from "./contract.js";
2
2
  /**
3
3
  * Listen for successful island module loads.
4
4
  *
package/dist/events.js CHANGED
@@ -1,13 +1,74 @@
1
+ // src/runtime-surface.ts
2
+ var SILENT_LOGGER = {
3
+ note() {},
4
+ flush() {}
5
+ };
6
+ function addListener(target, name, handler) {
7
+ const listener = (event) => handler(event.detail);
8
+ target.addEventListener(name, listener);
9
+ return () => target.removeEventListener(name, listener);
10
+ }
11
+ function dispatch(target, name, detail) {
12
+ target.dispatchEvent(new CustomEvent(name, { detail }));
13
+ }
14
+ function createRuntimeSurface(deps) {
15
+ return {
16
+ dispatchLoad(detail) {
17
+ dispatch(deps.target, "islands:load", detail);
18
+ },
19
+ dispatchError(detail) {
20
+ dispatch(deps.target, "islands:error", detail);
21
+ },
22
+ onLoad(handler) {
23
+ return addListener(deps.target, "islands:load", handler);
24
+ },
25
+ onError(handler) {
26
+ return addListener(deps.target, "islands:error", handler);
27
+ },
28
+ createLogger(tagName, debug) {
29
+ if (!debug)
30
+ return SILENT_LOGGER;
31
+ const msgs = [];
32
+ return {
33
+ note(msg) {
34
+ msgs.push(msg);
35
+ },
36
+ flush(summary) {
37
+ if (msgs.length === 0) {
38
+ deps.console.log("[islands]", `<${tagName}> ${summary}`);
39
+ } else {
40
+ deps.console.groupCollapsed(`[islands] <${tagName}> ${summary}`);
41
+ for (const msg of msgs)
42
+ deps.console.log(msg);
43
+ deps.console.groupEnd();
44
+ }
45
+ msgs.length = 0;
46
+ }
47
+ };
48
+ },
49
+ beginReadyLog(islandCount, debug) {
50
+ if (!debug)
51
+ return () => {};
52
+ deps.console.groupCollapsed(`[islands] ready — ${islandCount} island(s)`);
53
+ return () => deps.console.groupEnd();
54
+ }
55
+ };
56
+ }
57
+ var runtimeSurface;
58
+ function getRuntimeSurface() {
59
+ runtimeSurface ??= createRuntimeSurface({
60
+ target: document,
61
+ console
62
+ });
63
+ return runtimeSurface;
64
+ }
65
+
1
66
  // src/events.ts
2
67
  function onIslandLoad(handler) {
3
- const listener = (e) => handler(e.detail);
4
- document.addEventListener("islands:load", listener);
5
- return () => document.removeEventListener("islands:load", listener);
68
+ return getRuntimeSurface().onLoad(handler);
6
69
  }
7
70
  function onIslandError(handler) {
8
- const listener = (e) => handler(e.detail);
9
- document.addEventListener("islands:error", listener);
10
- return () => document.removeEventListener("islands:error", listener);
71
+ return getRuntimeSurface().onError(handler);
11
72
  }
12
73
  export {
13
74
  onIslandLoad,
package/dist/index.d.ts CHANGED
@@ -1,71 +1,8 @@
1
+ import type { ShopifyThemeIslandsOptions } from "./options.js";
1
2
  import type { Plugin } from "vite";
2
3
  /** A function that triggers the load of an island module. */
3
4
  export type ClientDirectiveLoader = () => Promise<void>;
4
5
  export type { ClientDirective, ClientDirectiveOptions } from "./contract.js";
5
- /** Plugin option entry for registering a custom client directive. */
6
- export interface ClientDirectiveDefinition {
7
- /** HTML attribute name, e.g. `'client:on-click'` */
8
- name: string;
9
- /** Path to the directive module (supports Vite aliases) */
10
- entrypoint: string;
11
- }
12
- /** Shared directive configuration shape used by both the plugin and the runtime. */
13
- export interface DirectivesConfig {
14
- /** Configuration for the `client:visible` directive (IntersectionObserver). */
15
- visible?: {
16
- /** HTML attribute name. Default: `'client:visible'` */
17
- attribute?: string;
18
- /** Passed to IntersectionObserver — loads islands before they scroll into view. Default: `'200px'` */
19
- rootMargin?: string;
20
- /** Passed to IntersectionObserver — ratio of element that must be visible. Default: `0` */
21
- threshold?: number;
22
- };
23
- /** Configuration for the `client:idle` directive (requestIdleCallback). */
24
- idle?: {
25
- /** HTML attribute name. Default: `'client:idle'` */
26
- attribute?: string;
27
- /** Deadline (ms) passed to requestIdleCallback; also used as the setTimeout fallback delay. Default: `500` */
28
- timeout?: number;
29
- };
30
- /** Configuration for the `client:media` directive (matchMedia). */
31
- media?: {
32
- /** HTML attribute name. Default: `'client:media'` */
33
- attribute?: string;
34
- };
35
- /** Configuration for the `client:defer` directive (fixed setTimeout delay). */
36
- defer?: {
37
- /** HTML attribute name. Default: `'client:defer'` */
38
- attribute?: string;
39
- /** Fallback delay (ms) when the attribute has no value. Default: `3000` */
40
- delay?: number;
41
- };
42
- /** Configuration for the `client:interaction` directive (mouseenter/touchstart/focusin). */
43
- interaction?: {
44
- /** HTML attribute name. Default: `'client:interaction'` */
45
- attribute?: string;
46
- /** DOM event names to listen for. Default: `['mouseenter', 'touchstart', 'focusin']` */
47
- events?: string[];
48
- };
49
- /** Custom client directives to register. Each entry maps an attribute name to a module entrypoint. */
50
- custom?: ClientDirectiveDefinition[];
51
- }
52
- /** Event detail and runtime options (single source of truth in contract). */
53
- import type { RetryConfig } from "./contract.js";
6
+ export type { ClientDirectiveDefinition, DirectivesConfig, ShopifyThemeIslandsOptions, } from "./options.js";
54
7
  export type { IslandLoadDetail, IslandErrorDetail, ReviveOptions, RetryConfig, RuntimeDirectivesConfig, } from "./contract.js";
55
- export interface ShopifyThemeIslandsOptions {
56
- /** Directories to scan for island files. Accepts paths or Vite aliases. Default: `['/frontend/js/islands/']` */
57
- directories?: string | string[];
58
- /** Log discovered islands and generated virtual module. Default: `false` */
59
- debug?: boolean;
60
- /** Per-directive configuration. */
61
- directives?: DirectivesConfig;
62
- /** Automatic retry behaviour for failed island loads. */
63
- retry?: RetryConfig;
64
- /**
65
- * Milliseconds before a custom directive that never calls `load()` is considered timed out.
66
- * When exceeded, `islands:error` is dispatched and the island is abandoned.
67
- * Default: `0` (disabled).
68
- */
69
- directiveTimeout?: number;
70
- }
71
8
  export default function shopifyThemeIslands(options?: ShopifyThemeIslandsOptions): Plugin;
package/dist/index.js CHANGED
@@ -54,39 +54,6 @@ function collectTagNames(dir) {
54
54
  return names;
55
55
  }
56
56
 
57
- // src/revive-module.ts
58
- function buildReviveModuleSource(params) {
59
- const { runtimePath, directoryGlobs, islandPaths, customDirectives, reviveOptions } = params;
60
- const directiveImportLines = customDirectives?.map(({ entrypoint }, index) => `import _directive${index} from ${JSON.stringify(entrypoint)};`) ?? [];
61
- const globEntries = [
62
- `{ ${directoryGlobs.map((glob) => `...import.meta.glob(${JSON.stringify(glob)})`).join(", ")} }`
63
- ];
64
- if (islandPaths?.length)
65
- globEntries.push(`import.meta.glob(${JSON.stringify(islandPaths)})`);
66
- const lines = [
67
- ...directiveImportLines,
68
- `import { revive as _islands } from ${JSON.stringify(runtimePath)};`,
69
- `const islands = Object.assign({}, ${globEntries.join(", ")});`,
70
- `const options = ${JSON.stringify(reviveOptions)};`
71
- ];
72
- if (customDirectives?.length) {
73
- const customDirectivesMapLines = customDirectives.map(({ name }, index) => ` [${JSON.stringify(name)}, _directive${index}]`);
74
- lines.push(`const customDirectives = new Map([
75
- ${customDirectivesMapLines.join(`,
76
- `)}
77
- ]);`);
78
- lines.push(`const payload = { islands, options, customDirectives };`);
79
- } else {
80
- lines.push(`const payload = { islands, options };`);
81
- }
82
- lines.push(`export const { disconnect } = _islands(payload);`);
83
- return lines.join(`
84
- `);
85
- }
86
-
87
- // src/index.ts
88
- import { fileURLToPath } from "node:url";
89
-
90
57
  // src/contract.ts
91
58
  var DEFAULT_DIRECTIVES = {
92
59
  visible: { attribute: "client:visible", rootMargin: "200px", threshold: 0 },
@@ -137,13 +104,17 @@ function buildIslandMap(payload) {
137
104
  return map;
138
105
  }
139
106
 
140
- // src/index.ts
141
- var VIRTUAL_ID = "vite-plugin-shopify-theme-islands/revive";
142
- var RESOLVED_ID = "\x00" + VIRTUAL_ID;
143
- var ISLAND_ID = "vite-plugin-shopify-theme-islands/island";
144
- var runtimePath = fileURLToPath(new URL("./runtime.js", import.meta.url));
145
- var islandPath = fileURLToPath(new URL("./island.js", import.meta.url));
107
+ // src/config-policy.ts
146
108
  var PREFIX = "[vite-plugin-shopify-theme-islands]";
109
+ function mergeDirectives(directives) {
110
+ return {
111
+ visible: { ...DEFAULT_DIRECTIVES.visible, ...directives?.visible },
112
+ idle: { ...DEFAULT_DIRECTIVES.idle, ...directives?.idle },
113
+ media: { ...DEFAULT_DIRECTIVES.media, ...directives?.media },
114
+ defer: { ...DEFAULT_DIRECTIVES.defer, ...directives?.defer },
115
+ interaction: { ...DEFAULT_DIRECTIVES.interaction, ...directives?.interaction }
116
+ };
117
+ }
147
118
  function validateOptions(options, directives) {
148
119
  const customDefs = options.directives?.custom ?? [];
149
120
  if (Array.isArray(options.directories) && options.directories.length === 0) {
@@ -180,6 +151,93 @@ function validateOptions(options, directives) {
180
151
  seen.add(def.name);
181
152
  }
182
153
  }
154
+ function resolveThemeIslandsPolicy(options = {}) {
155
+ const directives = mergeDirectives(options.directives);
156
+ validateOptions(options, directives);
157
+ const customDirectives = options.directives?.custom ?? [];
158
+ const debug = options.debug ?? false;
159
+ const runtime = {
160
+ directives,
161
+ debug,
162
+ ...options.retry !== undefined ? { retry: options.retry } : {},
163
+ ...options.directiveTimeout !== undefined ? { directiveTimeout: options.directiveTimeout } : {}
164
+ };
165
+ return {
166
+ plugin: {
167
+ directives,
168
+ customDirectives,
169
+ debug
170
+ },
171
+ runtime
172
+ };
173
+ }
174
+
175
+ // src/revive-module.ts
176
+ function buildReviveModuleSource(params) {
177
+ const { runtimePath, directoryGlobs, islandPaths, customDirectives, reviveOptions } = params;
178
+ const directiveImportLines = customDirectives?.map(({ entrypoint }, index) => `import _directive${index} from ${JSON.stringify(entrypoint)};`) ?? [];
179
+ const globEntries = [
180
+ `{ ${directoryGlobs.map((glob) => `...import.meta.glob(${JSON.stringify(glob)})`).join(", ")} }`
181
+ ];
182
+ if (islandPaths?.length)
183
+ globEntries.push(`import.meta.glob(${JSON.stringify(islandPaths)})`);
184
+ const lines = [
185
+ ...directiveImportLines,
186
+ `import { revive as _islands } from ${JSON.stringify(runtimePath)};`,
187
+ `const islands = Object.assign({}, ${globEntries.join(", ")});`,
188
+ `const options = ${JSON.stringify(reviveOptions)};`
189
+ ];
190
+ if (customDirectives?.length) {
191
+ const customDirectivesMapLines = customDirectives.map(({ name }, index) => ` [${JSON.stringify(name)}, _directive${index}]`);
192
+ lines.push(`const customDirectives = new Map([
193
+ ${customDirectivesMapLines.join(`,
194
+ `)}
195
+ ]);`);
196
+ lines.push(`const payload = { islands, options, customDirectives };`);
197
+ } else {
198
+ lines.push(`const payload = { islands, options };`);
199
+ }
200
+ lines.push(`export const { disconnect } = _islands(payload);`);
201
+ return lines.join(`
202
+ `);
203
+ }
204
+
205
+ // src/revive-bootstrap.ts
206
+ function createReviveBootstrapCompiler(ports, runtimePath) {
207
+ return {
208
+ async plan(input) {
209
+ const islandPaths = input.islandFiles.size > 0 ? ports.toLoadPaths(input.islandFiles, input.root) : null;
210
+ const customDirectives = input.customDirectives?.length ? await Promise.all(input.customDirectives.map(async ({ name, entrypoint }) => ({
211
+ name,
212
+ entrypoint: await ports.resolveEntrypoint(entrypoint)
213
+ }))) : null;
214
+ return {
215
+ runtimePath,
216
+ directoryGlobs: input.directories.map((dir) => dir + "**/*.{ts,js}"),
217
+ islandPaths,
218
+ customDirectives,
219
+ reviveOptions: input.reviveOptions
220
+ };
221
+ },
222
+ emit(plan) {
223
+ return buildReviveModuleSource({
224
+ runtimePath: plan.runtimePath,
225
+ directoryGlobs: plan.directoryGlobs,
226
+ islandPaths: plan.islandPaths,
227
+ customDirectives: plan.customDirectives?.length ? plan.customDirectives : undefined,
228
+ reviveOptions: plan.reviveOptions
229
+ });
230
+ }
231
+ };
232
+ }
233
+
234
+ // src/index.ts
235
+ import { fileURLToPath } from "node:url";
236
+ var VIRTUAL_ID = "vite-plugin-shopify-theme-islands/revive";
237
+ var RESOLVED_ID = "\x00" + VIRTUAL_ID;
238
+ var ISLAND_ID = "vite-plugin-shopify-theme-islands/island";
239
+ var runtimePath = fileURLToPath(new URL("./runtime.js", import.meta.url));
240
+ var islandPath = fileURLToPath(new URL("./island.js", import.meta.url));
183
241
  var defaultDirectories = ["/frontend/js/islands/"];
184
242
  function normalizeDir(dir) {
185
243
  return dir.endsWith("/") ? dir : dir + "/";
@@ -198,16 +256,9 @@ function resolveAliases(dirs, config) {
198
256
  }
199
257
  function shopifyThemeIslands(options = {}) {
200
258
  const rawDirs = (Array.isArray(options.directories) ? options.directories : [options.directories ?? defaultDirectories[0]]).map(normalizeDir);
201
- const directives = {
202
- visible: { ...DEFAULT_DIRECTIVES.visible, ...options.directives?.visible },
203
- idle: { ...DEFAULT_DIRECTIVES.idle, ...options.directives?.idle },
204
- media: { ...DEFAULT_DIRECTIVES.media, ...options.directives?.media },
205
- defer: { ...DEFAULT_DIRECTIVES.defer, ...options.directives?.defer },
206
- interaction: { ...DEFAULT_DIRECTIVES.interaction, ...options.directives?.interaction }
207
- };
208
- const clientDirectiveDefinitions = options.directives?.custom ?? [];
209
- validateOptions(options, directives);
210
- const debug = options.debug ?? false;
259
+ const policy = resolveThemeIslandsPolicy(options);
260
+ const { directives, customDirectives: clientDirectiveDefinitions, debug } = policy.plugin;
261
+ const { runtime: reviveOptions } = policy;
211
262
  const log = debug ? (...args) => console.log("[islands]", ...args) : () => {};
212
263
  let resolvedDirs = rawDirs;
213
264
  let root = process.cwd();
@@ -284,28 +335,24 @@ function shopifyThemeIslands(options = {}) {
284
335
  async load(id) {
285
336
  if (id !== RESOLVED_ID)
286
337
  return;
287
- const directoryGlobs = resolvedDirs.map((dir) => dir + "**/*.{ts,js}");
288
- const islandPaths = islandFiles.size > 0 ? getIslandPathsForLoad(islandFiles, root) : null;
289
- const customDirectives = [];
290
- for (const def of clientDirectiveDefinitions) {
291
- const resolved = await this.resolve(def.entrypoint);
292
- if (!resolved) {
293
- throw new Error(`[vite-plugin-shopify-theme-islands] Cannot resolve custom directive entrypoint: "${def.entrypoint}"`);
294
- }
295
- customDirectives.push({ name: def.name, entrypoint: resolved.id });
296
- }
297
- return buildReviveModuleSource({
298
- runtimePath,
299
- directoryGlobs,
300
- islandPaths,
301
- customDirectives,
302
- reviveOptions: {
303
- directives,
304
- debug,
305
- retry: options.retry,
306
- directiveTimeout: options.directiveTimeout
307
- }
338
+ const compiler = createReviveBootstrapCompiler({
339
+ resolveEntrypoint: async (entrypoint) => {
340
+ const resolved = await this.resolve(entrypoint);
341
+ if (!resolved) {
342
+ throw new Error(`[vite-plugin-shopify-theme-islands] Cannot resolve custom directive entrypoint: "${entrypoint}"`);
343
+ }
344
+ return resolved.id;
345
+ },
346
+ toLoadPaths: getIslandPathsForLoad
347
+ }, runtimePath);
348
+ const plan = await compiler.plan({
349
+ root,
350
+ directories: resolvedDirs,
351
+ islandFiles,
352
+ customDirectives: clientDirectiveDefinitions,
353
+ reviveOptions
308
354
  });
355
+ return compiler.emit(plan);
309
356
  }
310
357
  };
311
358
  }
@@ -0,0 +1,64 @@
1
+ import type { RetryConfig } from "./contract.js";
2
+ /** Plugin option entry for registering a custom client directive. */
3
+ export interface ClientDirectiveDefinition {
4
+ /** HTML attribute name, e.g. `'client:on-click'` */
5
+ name: string;
6
+ /** Path to the directive module (supports Vite aliases) */
7
+ entrypoint: string;
8
+ }
9
+ /** Shared directive configuration shape used by both the plugin and the runtime. */
10
+ export interface DirectivesConfig {
11
+ /** Configuration for the `client:visible` directive (IntersectionObserver). */
12
+ visible?: {
13
+ /** HTML attribute name. Default: `'client:visible'` */
14
+ attribute?: string;
15
+ /** Passed to IntersectionObserver — loads islands before they scroll into view. Default: `'200px'` */
16
+ rootMargin?: string;
17
+ /** Passed to IntersectionObserver — ratio of element that must be visible. Default: `0` */
18
+ threshold?: number;
19
+ };
20
+ /** Configuration for the `client:idle` directive (requestIdleCallback). */
21
+ idle?: {
22
+ /** HTML attribute name. Default: `'client:idle'` */
23
+ attribute?: string;
24
+ /** Deadline (ms) passed to requestIdleCallback; also used as the setTimeout fallback delay. Default: `500` */
25
+ timeout?: number;
26
+ };
27
+ /** Configuration for the `client:media` directive (matchMedia). */
28
+ media?: {
29
+ /** HTML attribute name. Default: `'client:media'` */
30
+ attribute?: string;
31
+ };
32
+ /** Configuration for the `client:defer` directive (fixed setTimeout delay). */
33
+ defer?: {
34
+ /** HTML attribute name. Default: `'client:defer'` */
35
+ attribute?: string;
36
+ /** Fallback delay (ms) when the attribute has no value. Default: `3000` */
37
+ delay?: number;
38
+ };
39
+ /** Configuration for the `client:interaction` directive (mouseenter/touchstart/focusin). */
40
+ interaction?: {
41
+ /** HTML attribute name. Default: `'client:interaction'` */
42
+ attribute?: string;
43
+ /** DOM event names to listen for. Default: `['mouseenter', 'touchstart', 'focusin']` */
44
+ events?: string[];
45
+ };
46
+ /** Custom client directives to register. Each entry maps an attribute name to a module entrypoint. */
47
+ custom?: ClientDirectiveDefinition[];
48
+ }
49
+ export interface ShopifyThemeIslandsOptions {
50
+ /** Directories to scan for island files. Accepts paths or Vite aliases. Default: `['/frontend/js/islands/']` */
51
+ directories?: string | string[];
52
+ /** Log discovered islands and generated virtual module. Default: `false` */
53
+ debug?: boolean;
54
+ /** Per-directive configuration. */
55
+ directives?: DirectivesConfig;
56
+ /** Automatic retry behaviour for failed island loads. */
57
+ retry?: RetryConfig;
58
+ /**
59
+ * Milliseconds before a custom directive that never calls `load()` is considered timed out.
60
+ * When exceeded, `islands:error` is dispatched and the island is abandoned.
61
+ * Default: `0` (disabled).
62
+ */
63
+ directiveTimeout?: number;
64
+ }
@@ -0,0 +1,31 @@
1
+ import type { ReviveOptions } from "./contract.js";
2
+ export interface ResolvedCustomDirective {
3
+ name: string;
4
+ entrypoint: string;
5
+ }
6
+ export interface ReviveBootstrapInputs {
7
+ root: string;
8
+ directories: string[];
9
+ islandFiles: Set<string>;
10
+ customDirectives?: Array<{
11
+ name: string;
12
+ entrypoint: string;
13
+ }>;
14
+ reviveOptions: ReviveOptions;
15
+ }
16
+ export interface ReviveBootstrapPlan {
17
+ runtimePath: string;
18
+ directoryGlobs: string[];
19
+ islandPaths: string[] | null;
20
+ customDirectives: ResolvedCustomDirective[] | null;
21
+ reviveOptions: ReviveOptions;
22
+ }
23
+ export interface ReviveBootstrapCompilerPorts {
24
+ resolveEntrypoint(entrypoint: string): Promise<string>;
25
+ toLoadPaths(islandFiles: Set<string>, root: string): string[];
26
+ }
27
+ export interface ReviveBootstrapCompiler {
28
+ plan(input: ReviveBootstrapInputs): Promise<ReviveBootstrapPlan>;
29
+ emit(plan: ReviveBootstrapPlan): string;
30
+ }
31
+ export declare function createReviveBootstrapCompiler(ports: ReviveBootstrapCompilerPorts, runtimePath: string): ReviveBootstrapCompiler;
@@ -0,0 +1,20 @@
1
+ import type { IslandErrorDetail, IslandLoadDetail } from "./contract.js";
2
+ export interface RuntimeLogger {
3
+ note(msg: string): void;
4
+ flush(summary: string): void;
5
+ }
6
+ export interface RuntimeSurface {
7
+ dispatchLoad(detail: IslandLoadDetail): void;
8
+ dispatchError(detail: IslandErrorDetail): void;
9
+ onLoad(handler: (detail: IslandLoadDetail) => void): () => void;
10
+ onError(handler: (detail: IslandErrorDetail) => void): () => void;
11
+ createLogger(tagName: string, debug: boolean): RuntimeLogger;
12
+ beginReadyLog(islandCount: number, debug: boolean): () => void;
13
+ }
14
+ interface RuntimeSurfaceDeps {
15
+ target: Document;
16
+ console: Pick<Console, "log" | "groupCollapsed" | "groupEnd">;
17
+ }
18
+ export declare function createRuntimeSurface(deps: RuntimeSurfaceDeps): RuntimeSurface;
19
+ export declare function getRuntimeSurface(): RuntimeSurface;
20
+ export {};