@notionhq/custom-blocks-host 0.3.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -225
  3. package/THIRD_PARTY_LICENSES.md +9 -0
  4. package/dist/autoBindProperties.d.ts +5 -2
  5. package/dist/autoBindProperties.d.ts.map +1 -1
  6. package/dist/autoBindProperties.js +5 -2
  7. package/dist/browser.js +1 -1
  8. package/dist/compatibility/addMetadataReadSchemasForProtocol3To4.d.ts +1215 -0
  9. package/dist/compatibility/addMetadataReadSchemasForProtocol3To4.d.ts.map +1 -0
  10. package/dist/compatibility/addMetadataReadSchemasForProtocol3To4.js +27 -0
  11. package/dist/compatibility/normalizeHostToSandboxMessage.d.ts +8 -0
  12. package/dist/compatibility/normalizeHostToSandboxMessage.d.ts.map +1 -0
  13. package/dist/compatibility/normalizeHostToSandboxMessage.js +39 -0
  14. package/dist/compatibility/normalizePageResultsForProtocol3To5.d.ts +11 -0
  15. package/dist/compatibility/normalizePageResultsForProtocol3To5.d.ts.map +1 -0
  16. package/dist/compatibility/normalizePageResultsForProtocol3To5.js +18 -0
  17. package/dist/compatibility/normalizePageResultsForProtocol6.d.ts +9 -0
  18. package/dist/compatibility/normalizePageResultsForProtocol6.d.ts.map +1 -0
  19. package/dist/compatibility/normalizePageResultsForProtocol6.js +18 -0
  20. package/dist/compatibility/normalizeSandboxToHostMessage.d.ts +1091 -0
  21. package/dist/compatibility/normalizeSandboxToHostMessage.d.ts.map +1 -0
  22. package/dist/compatibility/normalizeSandboxToHostMessage.js +9 -0
  23. package/dist/compatibility/pageForProtocol3To5.d.ts +159 -0
  24. package/dist/compatibility/pageForProtocol3To5.d.ts.map +1 -0
  25. package/dist/{lifecycle/legacyPage.js → compatibility/pageForProtocol3To5.js} +50 -9
  26. package/dist/compatibility/pageResult.d.ts +11 -0
  27. package/dist/compatibility/pageResult.d.ts.map +1 -0
  28. package/dist/compatibility/pageWithNullTextFallbackProperties.d.ts +9 -0
  29. package/dist/compatibility/pageWithNullTextFallbackProperties.d.ts.map +1 -0
  30. package/dist/compatibility/pageWithNullTextFallbackProperties.js +46 -0
  31. package/dist/createCustomBlockHost.d.ts +18 -19
  32. package/dist/createCustomBlockHost.d.ts.map +1 -1
  33. package/dist/createCustomBlockHost.js +103 -38
  34. package/dist/index.d.ts +2 -19
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -2
  37. package/dist/{localBlockUrl.d.ts → isAllowedLocalPreviewUrl.d.ts} +2 -2
  38. package/dist/isAllowedLocalPreviewUrl.d.ts.map +1 -0
  39. package/dist/{localBlockUrl.js → isAllowedLocalPreviewUrl.js} +3 -7
  40. package/dist/lifecycle/initErrors.d.ts +1 -0
  41. package/dist/lifecycle/initErrors.d.ts.map +1 -1
  42. package/dist/lifecycle/initErrors.js +7 -0
  43. package/dist/lifecycle/initializationController.d.ts +6 -4
  44. package/dist/lifecycle/initializationController.d.ts.map +1 -1
  45. package/dist/lifecycle/initializationController.js +24 -15
  46. package/dist/lifecycle/resolveManifest.d.ts +13 -0
  47. package/dist/lifecycle/resolveManifest.d.ts.map +1 -0
  48. package/dist/lifecycle/resolveManifest.js +21 -0
  49. package/dist/lifecycle/types.d.ts +1637 -17
  50. package/dist/lifecycle/types.d.ts.map +1 -1
  51. package/dist/lifecycle/types.js +18 -0
  52. package/dist/messages/sandboxMessageRouter.d.ts.map +1 -1
  53. package/dist/messages/sandboxMessageRouter.js +2 -2
  54. package/dist/protocol/dataSources/dataSourcePage.d.ts +3 -4
  55. package/dist/protocol/dataSources/dataSourcePage.js +2 -3
  56. package/dist/protocol/index.d.ts +1 -0
  57. package/dist/protocol/index.js +1 -0
  58. package/dist/protocol/isLocalBlockServerUrl.d.ts +2 -0
  59. package/dist/protocol/isLocalBlockServerUrl.js +9 -0
  60. package/dist/protocol/messages/connect.d.ts +2 -2
  61. package/dist/protocol/messages/connect.js +2 -2
  62. package/dist/protocol/messages/createPageResult.d.ts +2 -2
  63. package/dist/protocol/messages/createPageResult.js +3 -3
  64. package/dist/protocol/messages/getPage.d.ts +2 -2
  65. package/dist/protocol/messages/getPage.js +3 -3
  66. package/dist/protocol/messages/hostToSandbox.d.ts +3 -3
  67. package/dist/protocol/messages/hostToSandbox.js +10 -10
  68. package/dist/protocol/messages/init.d.ts +1 -1
  69. package/dist/protocol/messages/queryDataSourceResult.d.ts +3 -3
  70. package/dist/protocol/messages/queryDataSourceResult.js +6 -3
  71. package/dist/protocol/messages/updatePageResult.d.ts +2 -2
  72. package/dist/protocol/messages/updatePageResult.js +3 -3
  73. package/dist/protocol/pages/page.d.ts +2 -2
  74. package/dist/protocol/pages/page.js +1 -1
  75. package/dist/protocol/protocolVersion.d.ts +3 -2
  76. package/dist/protocol/protocolVersion.js +4 -2
  77. package/dist/protocol.d.ts +9 -0
  78. package/dist/protocol.d.ts.map +1 -0
  79. package/dist/protocol.js +8 -0
  80. package/docs/bridge/changelog.md +67 -0
  81. package/docs/bridge/protocol.md +182 -0
  82. package/docs/bridge/versioning.md +38 -0
  83. package/docs/compatibility.md +68 -0
  84. package/docs/handlers.md +199 -0
  85. package/docs/lifecycle.md +117 -0
  86. package/package.json +11 -3
  87. package/src/autoBindProperties.ts +5 -2
  88. package/src/compatibility/addMetadataReadSchemasForProtocol3To4.ts +36 -0
  89. package/src/compatibility/normalizeHostToSandboxMessage.ts +54 -0
  90. package/src/compatibility/normalizePageResultsForProtocol3To5.ts +28 -0
  91. package/src/compatibility/normalizePageResultsForProtocol6.ts +23 -0
  92. package/src/compatibility/normalizeSandboxToHostMessage.ts +10 -0
  93. package/src/{lifecycle/legacyPage.ts → compatibility/pageForProtocol3To5.ts} +52 -11
  94. package/src/compatibility/pageResult.ts +18 -0
  95. package/src/compatibility/pageWithNullTextFallbackProperties.ts +53 -0
  96. package/src/createCustomBlockHost.ts +152 -62
  97. package/src/index.ts +4 -51
  98. package/src/{localBlockUrl.ts → isAllowedLocalPreviewUrl.ts} +4 -7
  99. package/src/lifecycle/initErrors.ts +9 -0
  100. package/src/lifecycle/initializationController.ts +34 -19
  101. package/src/lifecycle/resolveManifest.ts +31 -0
  102. package/src/lifecycle/types.ts +84 -16
  103. package/src/messages/sandboxMessageRouter.ts +2 -2
  104. package/src/protocol.ts +8 -0
  105. package/dist/lifecycle/legacyPage.d.ts +0 -70
  106. package/dist/lifecycle/legacyPage.d.ts.map +0 -1
  107. package/dist/lifecycle/loadCustomBlockManifest.d.ts +0 -16
  108. package/dist/lifecycle/loadCustomBlockManifest.d.ts.map +0 -1
  109. package/dist/lifecycle/loadCustomBlockManifest.js +0 -65
  110. package/dist/lifecycle/manifestOptions.d.ts +0 -17
  111. package/dist/lifecycle/manifestOptions.d.ts.map +0 -1
  112. package/dist/lifecycle/normalizeHostToSandboxMessage.d.ts +0 -6
  113. package/dist/lifecycle/normalizeHostToSandboxMessage.d.ts.map +0 -1
  114. package/dist/lifecycle/normalizeHostToSandboxMessage.js +0 -16
  115. package/dist/lifecycle/normalizePage.d.ts +0 -7
  116. package/dist/lifecycle/normalizePage.d.ts.map +0 -1
  117. package/dist/lifecycle/normalizePage.js +0 -22
  118. package/dist/localBlockUrl.d.ts.map +0 -1
  119. package/src/lifecycle/loadCustomBlockManifest.ts +0 -89
  120. package/src/lifecycle/manifestOptions.ts +0 -19
  121. package/src/lifecycle/normalizeHostToSandboxMessage.ts +0 -29
  122. package/src/lifecycle/normalizePage.ts +0 -35
  123. /package/dist/{lifecycle/manifestOptions.js → compatibility/pageResult.js} +0 -0
@@ -1,14 +1,15 @@
1
1
  import { notionDataSourceBindingsSchema } from "./protocol/dataSources/dataSource.js";
2
2
  import { notionDataSourceIdSchema } from "./protocol/ids.js";
3
3
  import { hostToSandboxMessageSchema, } from "./protocol/messages/hostToSandbox.js";
4
- import { initMessageSchema, } from "./protocol/messages/init.js";
4
+ import { CustomBlockInitializationError, initMessageSchema, } from "./protocol/messages/init.js";
5
5
  import { LATEST_BRIDGE_PROTOCOL_VERSION } from "./protocol/protocolVersion.js";
6
6
  import * as v from "valibot";
7
- import { contextUnavailableError, invalidPropertyBindingError, missingDataSourceBindingError, missingPropertyBindingError, unknownInitializationError, } from "./lifecycle/initErrors.js";
7
+ import { normalizeHostToSandboxMessage } from "./compatibility/normalizeHostToSandboxMessage.js";
8
+ import { isAllowedLocalPreviewUrl } from "./isAllowedLocalPreviewUrl.js";
9
+ import { contextUnavailableError, invalidLocalPreviewUrlError, invalidPropertyBindingError, missingDataSourceBindingError, missingPropertyBindingError, unknownInitializationError, } from "./lifecycle/initErrors.js";
8
10
  import { createInitializationController } from "./lifecycle/initializationController.js";
9
- import { loadCustomBlockManifest } from "./lifecycle/loadCustomBlockManifest.js";
10
- import { normalizeHostToSandboxMessage } from "./lifecycle/normalizeHostToSandboxMessage.js";
11
- import { customBlockHostInitialStateSchema } from "./lifecycle/types.js";
11
+ import { resolveManifest } from "./lifecycle/resolveManifest.js";
12
+ import { customBlockHostInitialStateSchema, customBlockHostManifestResultSchema, customBlockHostPreparedStateResultSchema, } from "./lifecycle/types.js";
12
13
  import { parseExternalUrl } from "./messages/parseExternalUrl.js";
13
14
  import { createSandboxMessageRouter } from "./messages/sandboxMessageRouter.js";
14
15
  import { MIN_HOST_SUPPORTED_BRIDGE_PROTOCOL_VERSION } from "./protocolVersion.js";
@@ -20,7 +21,9 @@ import { unreachable } from "./utils.js";
20
21
  // Earlier SDKs cannot represent this context, so the host reports context_unavailable.
21
22
  const BRIDGE_PROTOCOL_VERSION_INTRODUCING_UNAVAILABLE_PAGE = 5;
22
23
  export function createCustomBlockHost(options) {
23
- const { iframe, prepareInitialState: prepareAdapterState, handlers, onInitialized, onConnectionFailure, onLog, onQueryUnsubscribed, sandboxOrigin, minBridgeProtocolVersion: configuredMinBridgeProtocolVersion, noConnectTimeoutMs, initialStateTimeoutMs, noInitResultTimeoutMs, } = options;
24
+ const { iframe, prepareInitialState: prepareAdapterState, handlers, onStatusChange, onLog, onQueryUnsubscribed, minBridgeProtocolVersion: configuredMinBridgeProtocolVersion, noConnectTimeoutMs, initialStateTimeoutMs, noInitResultTimeoutMs, } = options;
25
+ const sandboxUrl = parseSandboxUrl(options.sandboxUrl, options.manifestSource);
26
+ const sandboxOrigin = sandboxUrl.origin;
24
27
  // Callers can retire older SDKs, but cannot restore support for protocols
25
28
  // the runtime no longer implements. Omission uses the runtime minimum.
26
29
  const minBridgeProtocolVersion = Math.max(configuredMinBridgeProtocolVersion ??
@@ -46,7 +49,7 @@ export function createCustomBlockHost(options) {
46
49
  case "preparingInit":
47
50
  case "waitingForInitResult":
48
51
  case "initialized":
49
- case "error":
52
+ case "failed":
50
53
  break;
51
54
  // A stopped host must not send messages, including pending responses.
52
55
  // Return from the function to skip delivery below.
@@ -75,7 +78,7 @@ export function createCustomBlockHost(options) {
75
78
  case "waitingForConnect":
76
79
  case "preparingInit":
77
80
  case "waitingForInitResult":
78
- case "error":
81
+ case "failed":
79
82
  case "stopped":
80
83
  return;
81
84
  default:
@@ -149,7 +152,7 @@ export function createCustomBlockHost(options) {
149
152
  }
150
153
  function updateHostState(update) {
151
154
  if (initializationController.status === "stopped" ||
152
- initializationController.status === "error") {
155
+ initializationController.status === "failed") {
153
156
  return;
154
157
  }
155
158
  Object.assign(pendingState, update);
@@ -255,15 +258,29 @@ export function createCustomBlockHost(options) {
255
258
  }
256
259
  }
257
260
  const initializationController = createInitializationController({
261
+ manifestSource: options.manifestSource,
258
262
  async prepareInit(connect) {
263
+ const connectManifest = connect.status === "success" ? connect.manifest : undefined;
259
264
  sandboxBridgeProtocolVersion = connect.bridgeProtocolVersion;
260
- const result = await preparation;
265
+ onStatusChange({
266
+ status: "preparingInit",
267
+ localManifest: isAllowedLocalPreviewUrl({
268
+ url: sandboxUrl,
269
+ hostOrigin: window.location.origin,
270
+ })
271
+ ? connectManifest
272
+ : undefined,
273
+ bridgeProtocolVersion: connect.bridgeProtocolVersion,
274
+ sdkVersion: connect.sdkVersion,
275
+ });
276
+ const result = await (preparation ?? prepare(connectManifest));
261
277
  if (initializationController.status !== "preparingInit") {
262
278
  return result;
263
279
  }
264
280
  return finalizeInitialState(result);
265
281
  },
266
282
  sendInitMessage,
283
+ onInitSent: () => onStatusChange({ status: "waitingForInitResult" }),
267
284
  warn: payload => emit("warn", payload),
268
285
  flushPendingHostStateChanges,
269
286
  minBridgeProtocolVersion,
@@ -273,12 +290,16 @@ export function createCustomBlockHost(options) {
273
290
  stopHostWithFailure: stopWithFailure,
274
291
  onInitResult(message) {
275
292
  if (message.status === "success" && manifest !== undefined) {
276
- onInitialized?.({ manifest, initialHeight: message.initialHeight });
293
+ onStatusChange({
294
+ status: "initialized",
295
+ resolvedManifest: manifest,
296
+ initialHeight: message.initialHeight,
297
+ });
277
298
  }
278
299
  },
279
300
  onConnectionFailure: failure => {
280
301
  preparationController.abort();
281
- onConnectionFailure?.(failure);
302
+ onStatusChange({ status: "failed", error: failure });
282
303
  },
283
304
  });
284
305
  function finalizeInitialState(result) {
@@ -310,8 +331,21 @@ export function createCustomBlockHost(options) {
310
331
  hasPreparedInitialState = true;
311
332
  return { status: "success", initialState };
312
333
  }
313
- // Attach rejection handling immediately: preparation may finish before connect.
314
- const preparation = prepare().catch((error) => {
334
+ // Neither manifest source waits for the other. Observe rejections immediately,
335
+ // including failures from a host manifest that is not selected.
336
+ const hostManifest = readHostManifest().catch(handlePreparationError);
337
+ const preparation = options.manifestSource === "host"
338
+ ? prepare(undefined).catch(handlePreparationError)
339
+ : undefined;
340
+ async function readHostManifest() {
341
+ preparationController.signal.throwIfAborted();
342
+ const result = await options.getPersistedManifest({
343
+ signal: preparationController.signal,
344
+ });
345
+ preparationController.signal.throwIfAborted();
346
+ return v.parse(customBlockHostManifestResultSchema, result);
347
+ }
348
+ function handlePreparationError(error) {
315
349
  if (!preparationController.signal.aborted) {
316
350
  emit("warn", {
317
351
  message: "Failed to prepare custom block initialization",
@@ -319,34 +353,30 @@ export function createCustomBlockHost(options) {
319
353
  });
320
354
  }
321
355
  return { status: "error", error: unknownInitializationError() };
322
- });
323
- async function prepare() {
324
- const loaded = await loadCustomBlockManifest({
325
- ...options,
326
- sandboxOrigin,
327
- signal: preparationController.signal,
328
- onError: error => {
329
- emit("warn", {
330
- message: "Failed to load custom block manifest",
331
- error,
332
- });
333
- },
356
+ }
357
+ async function prepare(connectManifest) {
358
+ preparationController.signal.throwIfAborted();
359
+ const manifestResult = await resolveManifest({
360
+ manifestSource: options.manifestSource,
361
+ hostManifest,
362
+ connectManifest,
334
363
  });
335
- if (loaded.status === "error") {
336
- return loaded;
364
+ preparationController.signal.throwIfAborted();
365
+ if (manifestResult.status === "error") {
366
+ return manifestResult;
337
367
  }
338
- if (preparationController.signal.aborted) {
339
- return { status: "error", error: unknownInitializationError() };
340
- }
341
- const result = await prepareAdapterState({
342
- manifest: loaded.manifest,
368
+ const result = v.parse(customBlockHostPreparedStateResultSchema, await prepareAdapterState({
369
+ manifest: manifestResult.manifest,
343
370
  signal: preparationController.signal,
344
- });
371
+ }));
345
372
  return result.status === "error"
346
373
  ? result
347
374
  : {
348
375
  status: "success",
349
- initialState: { ...result.initialState, manifest: loaded.manifest },
376
+ initialState: {
377
+ ...result.initialState,
378
+ manifest: manifestResult.manifest,
379
+ },
350
380
  };
351
381
  }
352
382
  const onMessage = createSandboxMessageRouter({
@@ -372,7 +402,7 @@ export function createCustomBlockHost(options) {
372
402
  });
373
403
  window.addEventListener("message", onMessage);
374
404
  iframe.addEventListener("load", initializationController.onIframeLoad);
375
- function stop() {
405
+ function releaseResources() {
376
406
  navigationAbortController.abort();
377
407
  preparationController.abort();
378
408
  window.removeEventListener("message", onMessage);
@@ -380,11 +410,26 @@ export function createCustomBlockHost(options) {
380
410
  initializationController.stop();
381
411
  querySubscriptions.unsubscribeAll();
382
412
  }
413
+ function stop() {
414
+ const previousStatus = initializationController.status;
415
+ releaseResources();
416
+ if (previousStatus !== "stopped" && previousStatus !== "failed") {
417
+ onStatusChange({ status: "stopped" });
418
+ }
419
+ }
383
420
  function stopWithFailure(error) {
384
- stop();
421
+ if (initializationController.status === "stopped") {
422
+ return;
423
+ }
424
+ if (initializationController.status === "failed") {
425
+ releaseResources();
426
+ return;
427
+ }
428
+ releaseResources();
385
429
  emit("warn", error);
386
- onConnectionFailure?.(error);
430
+ onStatusChange({ status: "failed", error });
387
431
  }
432
+ onStatusChange({ status: "waitingForConnect" });
388
433
  return {
389
434
  stop,
390
435
  setTheme(theme) {
@@ -448,6 +493,26 @@ export function createCustomBlockHost(options) {
448
493
  },
449
494
  };
450
495
  }
496
+ function parseSandboxUrl(url, manifestSource) {
497
+ let parsed;
498
+ try {
499
+ parsed = new URL(url);
500
+ }
501
+ catch (error) {
502
+ if (manifestSource === "host") {
503
+ throw error;
504
+ }
505
+ throw new CustomBlockInitializationError(invalidLocalPreviewUrlError());
506
+ }
507
+ if (manifestSource === "sandbox" &&
508
+ !isAllowedLocalPreviewUrl({
509
+ url: parsed,
510
+ hostOrigin: window.location.origin,
511
+ })) {
512
+ throw new CustomBlockInitializationError(invalidLocalPreviewUrlError());
513
+ }
514
+ return parsed;
515
+ }
451
516
  function getCollectionSchema(dataSources, dataSourceId) {
452
517
  return Object.values(dataSources?.bindings ?? {}).find(binding => binding.collectionPointer?.id === dataSourceId)?.collectionSchema;
453
518
  }
package/dist/index.d.ts CHANGED
@@ -1,26 +1,9 @@
1
- export type { LegacyNotionDataSourcePageBridge } from "./protocol/dataSources/dataSourcePage.js";
2
- export type { NotionPropertySchemasById } from "./protocol/dataSources/propertySchema.js";
3
- export type { CustomBlockErrorInfo } from "./protocol/errors.js";
4
- export type { NotionPageId } from "./protocol/ids.js";
5
- export type { CustomBlockManifest } from "./protocol/manifest.js";
6
- export type { CreatePageMessage } from "./protocol/messages/createPage.js";
7
- export type { GetPageMessage } from "./protocol/messages/getPage.js";
8
- export type { GetUserMessage } from "./protocol/messages/getUser.js";
9
- export type { ListUsersMessage } from "./protocol/messages/listUsers.js";
10
- export type { OpenExternalUrlMessage } from "./protocol/messages/openExternalUrl.js";
11
- export type { OpenPageMessage } from "./protocol/messages/openPage.js";
12
- export type { CustomBlockCheckboxFilterOperator, CustomBlockContainsFilterOperator, CustomBlockCreatedByFilterOperator, CustomBlockDateFilterOperator, CustomBlockNumberFilterOperator, CustomBlockOptionFilterOperator, CustomBlockPeopleFilterOperator, CustomBlockPersonFilterValue, CustomBlockRelationFilterOperator, CustomBlockStatusFilterOperator, CustomBlockStatusGroupFilterOperator, CustomBlockStatusGroupName, CustomBlockTextFilterOperator, QueryDataSourceMessage, ResolvedCustomBlockDataSourceFilter, ResolvedCustomBlockDataSourcePropertyFilter, ResolvedCustomBlockDataSourceSort, } from "./protocol/messages/queryDataSource.js";
13
- export type { ResizeMessage } from "./protocol/messages/resize.js";
14
- export type { UpdatePageMessage } from "./protocol/messages/updatePage.js";
15
- export type { NotionDateInput, NotionFileInput, NotionPageCover, NotionPageData, NotionPageIcon, NotionPagePropertyReadMap, NotionPagePropertyValue, NotionPagePropertyWriteMap, NotionRichTextItem, NotionSelectOptionInput, } from "./protocol/pages/page.js";
16
- export { LATEST_BRIDGE_PROTOCOL_VERSION, LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION, } from "./protocol/protocolVersion.js";
17
1
  export { type AutoBindableProperty, getAutoBoundPropertyIdsByKey, } from "./autoBindProperties.js";
18
2
  export { type CustomBlockHostHandle, type CustomBlockHostOptions, createCustomBlockHost, } from "./createCustomBlockHost.js";
19
3
  export { type CustomBlockDateValue, InvalidNotionDateError, toNotionDateValue, } from "./dateValue.js";
20
4
  export { toNotionPageId } from "./ids.js";
21
- export type { CustomBlockHostManifestOptions } from "./lifecycle/manifestOptions.js";
22
- export type { ConnectSuccessMessage, CustomBlockHostDataSourcesPayload, CustomBlockHostInitialState, CustomBlockHostInitialStateResult, CustomBlockHostPreparedStateResult, CustomBlockHostPrepareInitialState, } from "./lifecycle/types.js";
23
- export { isLocalCustomBlockUrl } from "./localBlockUrl.js";
5
+ export { isAllowedLocalPreviewUrl } from "./isAllowedLocalPreviewUrl.js";
6
+ export type { CustomBlockHostDataSourcesPayload, CustomBlockHostInitialState, CustomBlockHostInitialStateResult, CustomBlockHostManifestResult, CustomBlockHostPreparedStateResult, CustomBlockHostPrepareInitialState, CustomBlockHostStatus, CustomBlockManifestSource, } from "./lifecycle/types.js";
24
7
  export type { CreatePageMessageInput, CustomBlockHostCreatePageResult, CustomBlockHostFailure, CustomBlockHostGetPageResult, CustomBlockHostGetUserResult, CustomBlockHostHandlers, CustomBlockHostListUsersResult, CustomBlockHostLogDirection, CustomBlockHostNavigationContext, CustomBlockHostOpenExternalUrlResult, CustomBlockHostOpenPageResult, CustomBlockHostUpdatePageResult, GetPageMessageInput, GetUserMessageInput, ListUsersMessageInput, OpenExternalUrlMessageInput, OpenPageMessageInput, QueryDataSourceMessageInput, ResizeMessageInput, UpdatePageMessageInput, } from "./messages/types.js";
25
8
  export type { CustomBlockHostQueryDataSourceResult } from "./queries/types.js";
26
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gCAAgC,EAAE,MAAM,gEAAgE,CAAA;AACtH,YAAY,EAAE,yBAAyB,EAAE,MAAM,gEAAgE,CAAA;AAC/G,YAAY,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAA;AACtF,YAAY,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAA;AAC3E,YAAY,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AACvF,YAAY,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,YAAY,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,YAAY,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,YAAY,EAAE,gBAAgB,EAAE,MAAM,wDAAwD,CAAA;AAC9F,YAAY,EAAE,sBAAsB,EAAE,MAAM,8DAA8D,CAAA;AAC1G,YAAY,EAAE,eAAe,EAAE,MAAM,uDAAuD,CAAA;AAC5F,YAAY,EACX,iCAAiC,EACjC,iCAAiC,EACjC,kCAAkC,EAClC,6BAA6B,EAC7B,+BAA+B,EAC/B,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,EAC/B,oCAAoC,EACpC,0BAA0B,EAC1B,6BAA6B,EAC7B,sBAAsB,EACtB,mCAAmC,EACnC,2CAA2C,EAC3C,iCAAiC,GACjC,MAAM,8DAA8D,CAAA;AACrE,YAAY,EAAE,aAAa,EAAE,MAAM,qDAAqD,CAAA;AACxF,YAAY,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,YAAY,EACX,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,gDAAgD,CAAA;AACvD,OAAO,EACN,8BAA8B,EAC9B,sCAAsC,GACtC,MAAM,qDAAqD,CAAA;AAC5D,OAAO,EACN,KAAK,oBAAoB,EACzB,4BAA4B,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,qBAAqB,GACrB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACN,KAAK,oBAAoB,EACzB,sBAAsB,EACtB,iBAAiB,GACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,YAAY,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AACpF,YAAY,EACX,qBAAqB,EACrB,iCAAiC,EACjC,2BAA2B,EAC3B,iCAAiC,EACjC,kCAAkC,EAClC,kCAAkC,GAClC,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,YAAY,EACX,sBAAsB,EACtB,+BAA+B,EAC/B,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,2BAA2B,EAC3B,gCAAgC,EAChC,oCAAoC,EACpC,6BAA6B,EAC7B,+BAA+B,EAC/B,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC3B,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,oCAAoC,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,oBAAoB,EACzB,4BAA4B,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,qBAAqB,GACrB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACN,KAAK,oBAAoB,EACzB,sBAAsB,EACtB,iBAAiB,GACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACxE,YAAY,EACX,iCAAiC,EACjC,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,kCAAkC,EAClC,kCAAkC,EAClC,qBAAqB,EACrB,yBAAyB,GACzB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACX,sBAAsB,EACtB,+BAA+B,EAC/B,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,2BAA2B,EAC3B,gCAAgC,EAChC,oCAAoC,EACpC,6BAA6B,EAC7B,+BAA+B,EAC/B,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,2BAA2B,EAC3B,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,oCAAoC,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
- export { LATEST_BRIDGE_PROTOCOL_VERSION, LEGACY_PROPERTY_SHAPE_PROTOCOL_VERSION, } from "./protocol/protocolVersion.js";
2
1
  export { getAutoBoundPropertyIdsByKey, } from "./autoBindProperties.js";
3
2
  export { createCustomBlockHost, } from "./createCustomBlockHost.js";
4
3
  export { InvalidNotionDateError, toNotionDateValue, } from "./dateValue.js";
5
4
  export { toNotionPageId } from "./ids.js";
6
- export { isLocalCustomBlockUrl } from "./localBlockUrl.js";
5
+ export { isAllowedLocalPreviewUrl } from "./isAllowedLocalPreviewUrl.js";
@@ -4,8 +4,8 @@
4
4
  * Local refers to the block server, not the environment where the host runs.
5
5
  * Requires the embedding page's origin and rejects URLs that share that origin.
6
6
  */
7
- export declare function isLocalCustomBlockUrl({ url, hostOrigin, }: {
7
+ export declare function isAllowedLocalPreviewUrl({ url, hostOrigin, }: {
8
8
  url: URL;
9
9
  hostOrigin: string;
10
10
  }): boolean;
11
- //# sourceMappingURL=localBlockUrl.d.ts.map
11
+ //# sourceMappingURL=isAllowedLocalPreviewUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isAllowedLocalPreviewUrl.d.ts","sourceRoot":"","sources":["../src/isAllowedLocalPreviewUrl.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,EACxC,GAAG,EACH,UAAU,GACV,EAAE;IACF,GAAG,EAAE,GAAG,CAAA;IACR,UAAU,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAOV"}
@@ -1,17 +1,13 @@
1
+ import { isLocalBlockServerUrl } from "./protocol/isLocalBlockServerUrl.js";
1
2
  /**
2
3
  * Checks whether a URL can serve a local custom block over HTTP or HTTPS.
3
4
  * Accepts localhost, any .localhost subdomain, and 127.0.0.1 without credentials.
4
5
  * Local refers to the block server, not the environment where the host runs.
5
6
  * Requires the embedding page's origin and rejects URLs that share that origin.
6
7
  */
7
- export function isLocalCustomBlockUrl({ url, hostOrigin, }) {
8
+ export function isAllowedLocalPreviewUrl({ url, hostOrigin, }) {
8
9
  return (typeof hostOrigin === "string" &&
9
10
  hostOrigin !== "" &&
10
11
  url.origin !== hostOrigin &&
11
- (url.protocol === "http:" || url.protocol === "https:") &&
12
- (url.hostname === "localhost" ||
13
- url.hostname === "127.0.0.1" ||
14
- url.hostname.endsWith(".localhost")) &&
15
- url.username === "" &&
16
- url.password === "");
12
+ isLocalBlockServerUrl(url));
17
13
  }
@@ -21,4 +21,5 @@ export declare function invalidPropertyBindingError(): CustomBlockErrorInfo<"inv
21
21
  export declare function noInitResultError(): CustomBlockErrorInfo<"no_init_result">;
22
22
  export declare function invalidInitResultPayloadError(): CustomBlockErrorInfo<"invalid_init_result_payload">;
23
23
  export declare function unknownInitializationError(): CustomBlockErrorInfo<"unknown_error">;
24
+ export declare function invalidLocalPreviewUrlError(): CustomBlockErrorInfo<"invalid_local_preview_url">;
24
25
  //# sourceMappingURL=initErrors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initErrors.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAOnE;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,yBAAyB,CAAC,CAO5F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IACjD,4BAA4B,EAAE,MAAM,GAAG,SAAS,CAAA;CAChD,GAAG,oBAAoB,CAAC,0BAA0B,CAAC,CAQnD;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACrD,4BAA4B,EAAE,MAAM,CAAA;IACpC,wBAAwB,EAAE,MAAM,CAAA;CAChC,GAAG,oBAAoB,CAAC,8BAA8B,CAAC,CAQvD;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAAC,qBAAqB,CAAC,CAOrF;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAOxF;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAO9F;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAQ9F;AAED,wBAAgB,iBAAiB,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,CAO1E;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,eAAe,CAAC,CAOlF"}
1
+ {"version":3,"file":"initErrors.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAAC,YAAY,CAAC,CAOnE;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,yBAAyB,CAAC,CAO5F;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IACjD,4BAA4B,EAAE,MAAM,GAAG,SAAS,CAAA;CAChD,GAAG,oBAAoB,CAAC,0BAA0B,CAAC,CAQnD;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE;IACrD,4BAA4B,EAAE,MAAM,CAAA;IACpC,wBAAwB,EAAE,MAAM,CAAA;CAChC,GAAG,oBAAoB,CAAC,8BAA8B,CAAC,CAQvD;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAAC,qBAAqB,CAAC,CAOrF;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAOxF;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAO9F;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAQ9F;AAED,wBAAgB,iBAAiB,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,CAO1E;AAED,wBAAgB,6BAA6B,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAOnG;AAED,wBAAgB,0BAA0B,IAAI,oBAAoB,CAAC,eAAe,CAAC,CAOlF;AAED,wBAAgB,2BAA2B,IAAI,oBAAoB,CAAC,2BAA2B,CAAC,CAO/F"}
@@ -102,3 +102,10 @@ export function unknownInitializationError() {
102
102
  isRetryable: false,
103
103
  };
104
104
  }
105
+ export function invalidLocalPreviewUrlError() {
106
+ return {
107
+ code: "invalid_local_preview_url",
108
+ message: "Local custom blocks require an HTTP(S) URL on localhost, a .localhost subdomain, or 127.0.0.1, without credentials and on a different origin from the host.",
109
+ isRetryable: false,
110
+ };
111
+ }
@@ -3,9 +3,10 @@ import type { CustomBlockInitErrorInfo, initMessageSchema } from "../protocol/me
3
3
  import type { InitResultMessage } from "../protocol/messages/initResult.js";
4
4
  import type { InferInput } from "valibot";
5
5
  import type { CustomBlockHostFailure } from "../messages/types.js";
6
- import type { ConnectSuccessMessage, CustomBlockHostInitialStateResult, InitStatus } from "./types.js";
6
+ import type { CustomBlockHostInitialStateResult, CustomBlockManifestSource, InitStatus } from "./types.js";
7
7
  export type InitializationControllerOptions = {
8
- prepareInit: (connect: ConnectSuccessMessage) => Promise<CustomBlockHostInitialStateResult>;
8
+ manifestSource: CustomBlockManifestSource;
9
+ prepareInit: (connect: ConnectMessage) => Promise<CustomBlockHostInitialStateResult>;
9
10
  sendInitMessage: (message: InferInput<typeof initMessageSchema>) => void;
10
11
  warn: (payload: unknown) => void;
11
12
  flushPendingHostStateChanges: () => void;
@@ -14,8 +15,9 @@ export type InitializationControllerOptions = {
14
15
  initialStateTimeoutMs?: number;
15
16
  noInitResultTimeoutMs?: number;
16
17
  stopHostWithFailure: (error: CustomBlockHostFailure) => void;
17
- onInitResult?: (message: InitResultMessage) => void;
18
- onConnectionFailure: ((error: CustomBlockHostFailure) => void) | undefined;
18
+ onInitResult: (message: InitResultMessage) => void;
19
+ onInitSent: () => void;
20
+ onConnectionFailure: (error: CustomBlockHostFailure) => void;
19
21
  };
20
22
  export type InitializationController = {
21
23
  readonly status: InitStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"initializationController.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initializationController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EACX,wBAAwB,EACxB,iBAAiB,EACjB,MAAM,mDAAmD,CAAA;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAWlE,OAAO,KAAK,EACX,qBAAqB,EACrB,iCAAiC,EACjC,UAAU,EACV,MAAM,YAAY,CAAA;AAMnB,MAAM,MAAM,+BAA+B,GAAG;IAC7C,WAAW,EAAE,CACZ,OAAO,EAAE,qBAAqB,KAC1B,OAAO,CAAC,iCAAiC,CAAC,CAAA;IAC/C,eAAe,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,IAAI,CAAA;IACxE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,4BAA4B,EAAE,MAAM,IAAI,CAAA;IACxC,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IAC5D,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACnD,mBAAmB,EAAE,CAAC,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAC1E,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,aAAa,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAChD,gBAAgB,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACtD,oBAAoB,EAAE,CAAC,IAAI,EAAE;QAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;QAC/B,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAA;KACzC,KAAK,SAAS,GAAG,MAAM,CAAA;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE;QAC/B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;KAC/B,KAAK,IAAI,CAAA;IACV,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,IAAI,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,+BAA+B,GACtC,wBAAwB,CAuV1B"}
1
+ {"version":3,"file":"initializationController.d.ts","sourceRoot":"","sources":["../../src/lifecycle/initializationController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sDAAsD,CAAA;AAC1F,OAAO,KAAK,EACX,wBAAwB,EACxB,iBAAiB,EACjB,MAAM,mDAAmD,CAAA;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yDAAyD,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAWlE,OAAO,KAAK,EACX,iCAAiC,EACjC,yBAAyB,EACzB,UAAU,EACV,MAAM,YAAY,CAAA;AAMnB,MAAM,MAAM,+BAA+B,GAAG;IAC7C,cAAc,EAAE,yBAAyB,CAAA;IACzC,WAAW,EAAE,CACZ,OAAO,EAAE,cAAc,KACnB,OAAO,CAAC,iCAAiC,CAAC,CAAA;IAC/C,eAAe,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,IAAI,CAAA;IACxE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,4BAA4B,EAAE,MAAM,IAAI,CAAA;IACxC,wBAAwB,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,mBAAmB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IAC5D,YAAY,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IAClD,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,mBAAmB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;CAC5D,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,aAAa,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAChD,gBAAgB,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACtD,oBAAoB,EAAE,CAAC,IAAI,EAAE;QAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;QAC/B,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAA;KACzC,KAAK,SAAS,GAAG,MAAM,CAAA;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE;QAC/B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;QACpC,KAAK,EAAE,wBAAwB,CAAA;KAC/B,KAAK,IAAI,CAAA;IACV,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,IAAI,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,+BAA+B,GACtC,wBAAwB,CAoW1B"}
@@ -6,7 +6,7 @@ const DEFAULT_NO_CONNECT_TIMEOUT_MS = 5_000;
6
6
  const DEFAULT_INITIAL_STATE_TIMEOUT_MS = 5_000;
7
7
  const DEFAULT_NO_INIT_RESULT_TIMEOUT_MS = 5_000;
8
8
  export function createInitializationController(options) {
9
- const { prepareInit, sendInitMessage, warn, flushPendingHostStateChanges, minBridgeProtocolVersion, noConnectTimeoutMs = DEFAULT_NO_CONNECT_TIMEOUT_MS, initialStateTimeoutMs = DEFAULT_INITIAL_STATE_TIMEOUT_MS, noInitResultTimeoutMs = DEFAULT_NO_INIT_RESULT_TIMEOUT_MS, stopHostWithFailure, onInitResult, onConnectionFailure, } = options;
9
+ const { manifestSource, prepareInit, sendInitMessage, warn, flushPendingHostStateChanges, minBridgeProtocolVersion, noConnectTimeoutMs = DEFAULT_NO_CONNECT_TIMEOUT_MS, initialStateTimeoutMs = DEFAULT_INITIAL_STATE_TIMEOUT_MS, noInitResultTimeoutMs = DEFAULT_NO_INIT_RESULT_TIMEOUT_MS, stopHostWithFailure, onInitResult, onInitSent, onConnectionFailure, } = options;
10
10
  let initStatus = "waitingForConnect";
11
11
  let noConnectTimeoutId;
12
12
  let initialStateTimeoutId;
@@ -40,13 +40,13 @@ export function createInitializationController(options) {
40
40
  break;
41
41
  case "waitingForInitResult":
42
42
  case "initialized":
43
- case "error":
43
+ case "failed":
44
44
  case "stopped":
45
45
  return;
46
46
  default:
47
47
  return unreachable(initStatus);
48
48
  }
49
- initStatus = "error";
49
+ initStatus = "failed";
50
50
  activeInitializationId = initializationId;
51
51
  clearNoConnectTimeout();
52
52
  clearInitialStateTimeout();
@@ -56,7 +56,7 @@ export function createInitializationController(options) {
56
56
  status: "error",
57
57
  error,
58
58
  });
59
- onConnectionFailure?.({ ...error, phase, source });
59
+ onConnectionFailure({ ...error, phase, source });
60
60
  }
61
61
  async function prepareAndSendInit(connect) {
62
62
  if (initStatus !== "waitingForConnect") {
@@ -111,13 +111,20 @@ export function createInitializationController(options) {
111
111
  dataSources: preparation.initialState.dataSources,
112
112
  };
113
113
  sendInitMessage(message);
114
+ if (initStatus !== "waitingForInitResult") {
115
+ return;
116
+ }
117
+ onInitSent();
118
+ if (initStatus !== "waitingForInitResult") {
119
+ return;
120
+ }
114
121
  noInitResultTimeoutId = window.setTimeout(() => {
115
122
  if (initStatus !== "waitingForInitResult") {
116
123
  return;
117
124
  }
118
- initStatus = "error";
125
+ initStatus = "failed";
119
126
  const error = noInitResultError();
120
- onConnectionFailure?.({ ...error, phase: "initResult", source: "host" });
127
+ onConnectionFailure({ ...error, phase: "initResult", source: "host" });
121
128
  warn({
122
129
  ...error,
123
130
  initializationId: connect.initializationId,
@@ -173,8 +180,10 @@ export function createInitializationController(options) {
173
180
  });
174
181
  return;
175
182
  }
176
- // If the sandbox reported an error during `connect`, return it as an `init` error.
177
- if (message.status === "error") {
183
+ // Invalid sandbox metadata does not prevent initialization from a host manifest.
184
+ if (message.status === "error" &&
185
+ (manifestSource === "sandbox" ||
186
+ message.error.code !== "manifest_invalid")) {
178
187
  sendInitError({
179
188
  initializationId: message.initializationId,
180
189
  error: message.error,
@@ -225,9 +234,9 @@ export function createInitializationController(options) {
225
234
  }
226
235
  clearNoConnectTimeout();
227
236
  clearNoInitResultTimeout();
228
- initStatus = "error";
237
+ initStatus = "failed";
229
238
  warn(error);
230
- onConnectionFailure?.({ ...error, phase: "initResult", source: "host" });
239
+ onConnectionFailure({ ...error, phase: "initResult", source: "host" });
231
240
  }
232
241
  function onIframeLoad() {
233
242
  if (initStatus === "stopped") {
@@ -254,10 +263,10 @@ export function createInitializationController(options) {
254
263
  // Only do anything if the iframe loaded before the `connect` message was sent.
255
264
  return;
256
265
  }
257
- initStatus = "error";
266
+ initStatus = "failed";
258
267
  const error = noConnectError();
259
268
  warn(error);
260
- onConnectionFailure?.({ ...error, phase: "connect", source: "host" });
269
+ onConnectionFailure({ ...error, phase: "connect", source: "host" });
261
270
  }, noConnectTimeoutMs);
262
271
  }
263
272
  function handleInitResult(message) {
@@ -270,18 +279,18 @@ export function createInitializationController(options) {
270
279
  return;
271
280
  }
272
281
  clearNoInitResultTimeout();
273
- initStatus = message.status === "success" ? "initialized" : "error";
282
+ initStatus = message.status === "success" ? "initialized" : "failed";
274
283
  if (message.status === "success") {
275
284
  flushPendingHostStateChanges();
276
285
  }
277
286
  else {
278
- onConnectionFailure?.({
287
+ onConnectionFailure({
279
288
  ...message.error,
280
289
  phase: "initResult",
281
290
  source: "sandbox",
282
291
  });
283
292
  }
284
- onInitResult?.(message);
293
+ onInitResult(message);
285
294
  }
286
295
  function stop() {
287
296
  initStatus = "stopped";
@@ -0,0 +1,13 @@
1
+ import type { CustomBlockManifest } from "../protocol/manifest.js";
2
+ import type { CustomBlockHostNormalizedManifestResult, CustomBlockManifestSource } from "./types.js";
3
+ /**
4
+ * Select the host's manifest result or the sandbox's connect declaration. Both
5
+ * sources are already validated. Forward host errors unchanged, and report
6
+ * manifest_unavailable if the sandbox omits its declaration.
7
+ */
8
+ export declare function resolveManifest(args: {
9
+ manifestSource: CustomBlockManifestSource;
10
+ hostManifest: Promise<CustomBlockHostNormalizedManifestResult>;
11
+ connectManifest: CustomBlockManifest | undefined;
12
+ }): Promise<CustomBlockHostNormalizedManifestResult>;
13
+ //# sourceMappingURL=resolveManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveManifest.d.ts","sourceRoot":"","sources":["../../src/lifecycle/resolveManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AACvF,OAAO,KAAK,EACX,uCAAuC,EACvC,yBAAyB,EACzB,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC3C,cAAc,EAAE,yBAAyB,CAAA;IACzC,YAAY,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAA;IAC9D,eAAe,EAAE,mBAAmB,GAAG,SAAS,CAAA;CAChD,GAAG,OAAO,CAAC,uCAAuC,CAAC,CAenD"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Select the host's manifest result or the sandbox's connect declaration. Both
3
+ * sources are already validated. Forward host errors unchanged, and report
4
+ * manifest_unavailable if the sandbox omits its declaration.
5
+ */
6
+ export async function resolveManifest(args) {
7
+ if (args.manifestSource === "host") {
8
+ return args.hostManifest;
9
+ }
10
+ if (args.connectManifest !== undefined) {
11
+ return { status: "success", manifest: args.connectManifest };
12
+ }
13
+ return {
14
+ status: "error",
15
+ error: {
16
+ code: "manifest_unavailable",
17
+ message: "The sandbox did not provide a manifest in connect.",
18
+ isRetryable: false,
19
+ },
20
+ };
21
+ }