@notionhq/custom-blocks 0.0.58

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 (298) hide show
  1. package/HOST.md +171 -0
  2. package/README.md +57 -0
  3. package/bin/cli/attach.js +180 -0
  4. package/bin/cli/cli.js +248 -0
  5. package/bin/cli/create.js +106 -0
  6. package/bin/cli/datasources.js +255 -0
  7. package/bin/cli/deploy.js +109 -0
  8. package/bin/cli/ids.js +13 -0
  9. package/bin/cli/ntn.js +95 -0
  10. package/bin/cli/pullData.js +76 -0
  11. package/bin/cli/pullManifest.js +158 -0
  12. package/bin/cli/target.js +95 -0
  13. package/bin/src/bridge/dataSources/propertySchema.js +148 -0
  14. package/bin/src/bridge/manifest.js +40 -0
  15. package/dist/autoResize.d.ts +4 -0
  16. package/dist/autoResize.d.ts.map +1 -0
  17. package/dist/autoResize.js +71 -0
  18. package/dist/bridge/SandboxBridge.d.ts +92 -0
  19. package/dist/bridge/SandboxBridge.d.ts.map +1 -0
  20. package/dist/bridge/SandboxBridge.js +718 -0
  21. package/dist/bridge/dataSources/dataSource.d.ts +732 -0
  22. package/dist/bridge/dataSources/dataSource.d.ts.map +1 -0
  23. package/dist/bridge/dataSources/dataSource.js +37 -0
  24. package/dist/bridge/dataSources/dataSourcePage.d.ts +118 -0
  25. package/dist/bridge/dataSources/dataSourcePage.d.ts.map +1 -0
  26. package/dist/bridge/dataSources/dataSourcePage.js +14 -0
  27. package/dist/bridge/dataSources/dataSourceValue.d.ts +67 -0
  28. package/dist/bridge/dataSources/dataSourceValue.d.ts.map +1 -0
  29. package/dist/bridge/dataSources/dataSourceValue.js +14 -0
  30. package/dist/bridge/dataSources/dateValue.d.ts +158 -0
  31. package/dist/bridge/dataSources/dateValue.d.ts.map +1 -0
  32. package/dist/bridge/dataSources/dateValue.js +59 -0
  33. package/dist/bridge/dataSources/errors.d.ts +6 -0
  34. package/dist/bridge/dataSources/errors.d.ts.map +1 -0
  35. package/dist/bridge/dataSources/errors.js +4 -0
  36. package/dist/bridge/dataSources/propertySchema.d.ts +191 -0
  37. package/dist/bridge/dataSources/propertySchema.d.ts.map +1 -0
  38. package/dist/bridge/dataSources/propertySchema.js +148 -0
  39. package/dist/bridge/dataSources/recordPointer.d.ts +10 -0
  40. package/dist/bridge/dataSources/recordPointer.d.ts.map +1 -0
  41. package/dist/bridge/dataSources/recordPointer.js +8 -0
  42. package/dist/bridge/dataSources/resolve.d.ts +22 -0
  43. package/dist/bridge/dataSources/resolve.d.ts.map +1 -0
  44. package/dist/bridge/dataSources/resolve.js +65 -0
  45. package/dist/bridge/dataSources/resolveProperty.d.ts +41 -0
  46. package/dist/bridge/dataSources/resolveProperty.d.ts.map +1 -0
  47. package/dist/bridge/dataSources/resolveProperty.js +73 -0
  48. package/dist/bridge/errors.d.ts +12 -0
  49. package/dist/bridge/errors.d.ts.map +1 -0
  50. package/dist/bridge/errors.js +6 -0
  51. package/dist/bridge/hostState.d.ts +65 -0
  52. package/dist/bridge/hostState.d.ts.map +1 -0
  53. package/dist/bridge/hostState.js +65 -0
  54. package/dist/bridge/ids.d.ts +39 -0
  55. package/dist/bridge/ids.d.ts.map +1 -0
  56. package/dist/bridge/ids.js +5 -0
  57. package/dist/bridge/incomingType.d.ts +10 -0
  58. package/dist/bridge/incomingType.d.ts.map +1 -0
  59. package/dist/bridge/incomingType.js +17 -0
  60. package/dist/bridge/loadManifest.d.ts +25 -0
  61. package/dist/bridge/loadManifest.d.ts.map +1 -0
  62. package/dist/bridge/loadManifest.js +68 -0
  63. package/dist/bridge/manifest.d.ts +66 -0
  64. package/dist/bridge/manifest.d.ts.map +1 -0
  65. package/dist/bridge/manifest.js +40 -0
  66. package/dist/bridge/messages/createPage.d.ts +225 -0
  67. package/dist/bridge/messages/createPage.d.ts.map +1 -0
  68. package/dist/bridge/messages/createPage.js +46 -0
  69. package/dist/bridge/messages/createPageResult.d.ts +211 -0
  70. package/dist/bridge/messages/createPageResult.d.ts.map +1 -0
  71. package/dist/bridge/messages/createPageResult.js +28 -0
  72. package/dist/bridge/messages/currentUserChanged.d.ts +19 -0
  73. package/dist/bridge/messages/currentUserChanged.d.ts.map +1 -0
  74. package/dist/bridge/messages/currentUserChanged.js +9 -0
  75. package/dist/bridge/messages/dataSourcesChanged.d.ts +158 -0
  76. package/dist/bridge/messages/dataSourcesChanged.d.ts.map +1 -0
  77. package/dist/bridge/messages/dataSourcesChanged.js +13 -0
  78. package/dist/bridge/messages/getPage.d.ts +216 -0
  79. package/dist/bridge/messages/getPage.d.ts.map +1 -0
  80. package/dist/bridge/messages/getPage.js +33 -0
  81. package/dist/bridge/messages/getUser.d.ts +45 -0
  82. package/dist/bridge/messages/getUser.d.ts.map +1 -0
  83. package/dist/bridge/messages/getUser.js +32 -0
  84. package/dist/bridge/messages/hostToSandbox.d.ts +1089 -0
  85. package/dist/bridge/messages/hostToSandbox.d.ts.map +1 -0
  86. package/dist/bridge/messages/hostToSandbox.js +32 -0
  87. package/dist/bridge/messages/init.d.ts +209 -0
  88. package/dist/bridge/messages/init.d.ts.map +1 -0
  89. package/dist/bridge/messages/init.js +47 -0
  90. package/dist/bridge/messages/invalidHostMessage.d.ts +15 -0
  91. package/dist/bridge/messages/invalidHostMessage.d.ts.map +1 -0
  92. package/dist/bridge/messages/invalidHostMessage.js +13 -0
  93. package/dist/bridge/messages/invalidSandboxMessage.d.ts +15 -0
  94. package/dist/bridge/messages/invalidSandboxMessage.d.ts.map +1 -0
  95. package/dist/bridge/messages/invalidSandboxMessage.js +13 -0
  96. package/dist/bridge/messages/listUsers.d.ts +53 -0
  97. package/dist/bridge/messages/listUsers.d.ts.map +1 -0
  98. package/dist/bridge/messages/listUsers.js +33 -0
  99. package/dist/bridge/messages/pageChanged.d.ts +12 -0
  100. package/dist/bridge/messages/pageChanged.d.ts.map +1 -0
  101. package/dist/bridge/messages/pageChanged.js +9 -0
  102. package/dist/bridge/messages/parentChanged.d.ts +22 -0
  103. package/dist/bridge/messages/parentChanged.d.ts.map +1 -0
  104. package/dist/bridge/messages/parentChanged.js +9 -0
  105. package/dist/bridge/messages/queryDataSource.d.ts +20 -0
  106. package/dist/bridge/messages/queryDataSource.d.ts.map +1 -0
  107. package/dist/bridge/messages/queryDataSource.js +19 -0
  108. package/dist/bridge/messages/queryDataSourceResult.d.ts +90 -0
  109. package/dist/bridge/messages/queryDataSourceResult.d.ts.map +1 -0
  110. package/dist/bridge/messages/queryDataSourceResult.js +21 -0
  111. package/dist/bridge/messages/ready.d.ts +45 -0
  112. package/dist/bridge/messages/ready.d.ts.map +1 -0
  113. package/dist/bridge/messages/ready.js +37 -0
  114. package/dist/bridge/messages/resize.d.ts +12 -0
  115. package/dist/bridge/messages/resize.d.ts.map +1 -0
  116. package/dist/bridge/messages/resize.js +10 -0
  117. package/dist/bridge/messages/sandboxToHost.d.ts +410 -0
  118. package/dist/bridge/messages/sandboxToHost.d.ts.map +1 -0
  119. package/dist/bridge/messages/sandboxToHost.js +25 -0
  120. package/dist/bridge/messages/themeChanged.d.ts +11 -0
  121. package/dist/bridge/messages/themeChanged.d.ts.map +1 -0
  122. package/dist/bridge/messages/themeChanged.js +10 -0
  123. package/dist/bridge/messages/updatePage.d.ts +171 -0
  124. package/dist/bridge/messages/updatePage.d.ts.map +1 -0
  125. package/dist/bridge/messages/updatePage.js +15 -0
  126. package/dist/bridge/messages/updatePageResult.d.ts +210 -0
  127. package/dist/bridge/messages/updatePageResult.d.ts.map +1 -0
  128. package/dist/bridge/messages/updatePageResult.js +27 -0
  129. package/dist/bridge/pages/page.d.ts +600 -0
  130. package/dist/bridge/pages/page.d.ts.map +1 -0
  131. package/dist/bridge/pages/page.js +217 -0
  132. package/dist/bridge/parent.d.ts +25 -0
  133. package/dist/bridge/parent.d.ts.map +1 -0
  134. package/dist/bridge/parent.js +11 -0
  135. package/dist/bridge/pendingRequests.d.ts +14 -0
  136. package/dist/bridge/pendingRequests.d.ts.map +1 -0
  137. package/dist/bridge/pendingRequests.js +27 -0
  138. package/dist/bridge/sandboxClient.d.ts +63 -0
  139. package/dist/bridge/sandboxClient.d.ts.map +1 -0
  140. package/dist/bridge/sandboxClient.js +92 -0
  141. package/dist/bridge/theme.d.ts +4 -0
  142. package/dist/bridge/theme.d.ts.map +1 -0
  143. package/dist/bridge/theme.js +2 -0
  144. package/dist/bridge/users/user.d.ts +36 -0
  145. package/dist/bridge/users/user.d.ts.map +1 -0
  146. package/dist/bridge/users/user.js +19 -0
  147. package/dist/customBlock.d.ts +36 -0
  148. package/dist/customBlock.d.ts.map +1 -0
  149. package/dist/customBlock.js +65 -0
  150. package/dist/host/createCustomBlockHost.d.ts +34 -0
  151. package/dist/host/createCustomBlockHost.d.ts.map +1 -0
  152. package/dist/host/createCustomBlockHost.js +278 -0
  153. package/dist/host/lifecycle/initErrors.d.ts +10 -0
  154. package/dist/host/lifecycle/initErrors.d.ts.map +1 -0
  155. package/dist/host/lifecycle/initErrors.js +123 -0
  156. package/dist/host/lifecycle/ready.d.ts +8 -0
  157. package/dist/host/lifecycle/ready.d.ts.map +1 -0
  158. package/dist/host/lifecycle/ready.js +24 -0
  159. package/dist/host/lifecycle/types.d.ts +24 -0
  160. package/dist/host/lifecycle/types.d.ts.map +1 -0
  161. package/dist/host/lifecycle/types.js +1 -0
  162. package/dist/host/messages/invalidSandboxMessage.d.ts +7 -0
  163. package/dist/host/messages/invalidSandboxMessage.d.ts.map +1 -0
  164. package/dist/host/messages/invalidSandboxMessage.js +24 -0
  165. package/dist/host/messages/types.d.ts +60 -0
  166. package/dist/host/messages/types.d.ts.map +1 -0
  167. package/dist/host/messages/types.js +1 -0
  168. package/dist/host/queries/querySubscriptions.d.ts +20 -0
  169. package/dist/host/queries/querySubscriptions.d.ts.map +1 -0
  170. package/dist/host/queries/querySubscriptions.js +29 -0
  171. package/dist/host/queries/types.d.ts +9 -0
  172. package/dist/host/queries/types.d.ts.map +1 -0
  173. package/dist/host/queries/types.js +1 -0
  174. package/dist/host.d.ts +73 -0
  175. package/dist/host.d.ts.map +1 -0
  176. package/dist/host.js +42 -0
  177. package/dist/index.d.ts +37 -0
  178. package/dist/index.d.ts.map +1 -0
  179. package/dist/index.js +14 -0
  180. package/dist/init.d.ts +53 -0
  181. package/dist/init.d.ts.map +1 -0
  182. package/dist/init.js +87 -0
  183. package/dist/react/DebugMessageLog.d.ts +2 -0
  184. package/dist/react/DebugMessageLog.d.ts.map +1 -0
  185. package/dist/react/DebugMessageLog.js +22 -0
  186. package/dist/react/NotionCustomBlock.css +110 -0
  187. package/dist/react/NotionCustomBlock.d.ts +50 -0
  188. package/dist/react/NotionCustomBlock.d.ts.map +1 -0
  189. package/dist/react/NotionCustomBlock.js +81 -0
  190. package/dist/react/index.d.ts +14 -0
  191. package/dist/react/index.d.ts.map +1 -0
  192. package/dist/react/index.js +13 -0
  193. package/dist/react/standalonePreview.d.ts +2 -0
  194. package/dist/react/standalonePreview.d.ts.map +1 -0
  195. package/dist/react/standalonePreview.js +26 -0
  196. package/dist/react/useCustomBlockAutoResize.d.ts +30 -0
  197. package/dist/react/useCustomBlockAutoResize.d.ts.map +1 -0
  198. package/dist/react/useCustomBlockAutoResize.js +35 -0
  199. package/dist/react/useCustomBlockInit.d.ts +43 -0
  200. package/dist/react/useCustomBlockInit.d.ts.map +1 -0
  201. package/dist/react/useCustomBlockInit.js +60 -0
  202. package/dist/react/useDataSource.d.ts +13 -0
  203. package/dist/react/useDataSource.d.ts.map +1 -0
  204. package/dist/react/useDataSource.js +37 -0
  205. package/dist/react/useHostState.d.ts +2 -0
  206. package/dist/react/useHostState.d.ts.map +1 -0
  207. package/dist/react/useHostState.js +5 -0
  208. package/dist/react/useRuntimeState.d.ts +66 -0
  209. package/dist/react/useRuntimeState.d.ts.map +1 -0
  210. package/dist/react/useRuntimeState.js +73 -0
  211. package/dist/types.d.ts +154 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +1 -0
  214. package/dist/utils.d.ts +9 -0
  215. package/dist/utils.d.ts.map +1 -0
  216. package/dist/utils.js +10 -0
  217. package/dist/version.d.ts +9 -0
  218. package/dist/version.d.ts.map +1 -0
  219. package/dist/version.js +7 -0
  220. package/docs/block-location.md +83 -0
  221. package/docs/data-sources.md +186 -0
  222. package/docs/lifecycle.md +172 -0
  223. package/docs/manifest.md +42 -0
  224. package/docs/pages.md +143 -0
  225. package/docs/users.md +92 -0
  226. package/package.json +69 -0
  227. package/src/autoResize.ts +84 -0
  228. package/src/bridge/SandboxBridge.ts +921 -0
  229. package/src/bridge/dataSources/dataSource.ts +63 -0
  230. package/src/bridge/dataSources/dataSourcePage.ts +71 -0
  231. package/src/bridge/dataSources/dataSourceValue.ts +19 -0
  232. package/src/bridge/dataSources/dateValue.ts +96 -0
  233. package/src/bridge/dataSources/errors.ts +14 -0
  234. package/src/bridge/dataSources/propertySchema.ts +186 -0
  235. package/src/bridge/dataSources/recordPointer.ts +13 -0
  236. package/src/bridge/dataSources/resolve.ts +99 -0
  237. package/src/bridge/dataSources/resolveProperty.ts +130 -0
  238. package/src/bridge/errors.ts +13 -0
  239. package/src/bridge/hostState.ts +154 -0
  240. package/src/bridge/ids.ts +58 -0
  241. package/src/bridge/incomingType.ts +19 -0
  242. package/src/bridge/loadManifest.ts +89 -0
  243. package/src/bridge/manifest.ts +53 -0
  244. package/src/bridge/messages/createPage.ts +67 -0
  245. package/src/bridge/messages/createPageResult.ts +52 -0
  246. package/src/bridge/messages/currentUserChanged.ts +14 -0
  247. package/src/bridge/messages/dataSourcesChanged.ts +18 -0
  248. package/src/bridge/messages/getPage.ts +52 -0
  249. package/src/bridge/messages/getUser.ts +48 -0
  250. package/src/bridge/messages/hostToSandbox.ts +37 -0
  251. package/src/bridge/messages/init.ts +81 -0
  252. package/src/bridge/messages/invalidHostMessage.ts +16 -0
  253. package/src/bridge/messages/invalidSandboxMessage.ts +18 -0
  254. package/src/bridge/messages/listUsers.ts +49 -0
  255. package/src/bridge/messages/pageChanged.ts +12 -0
  256. package/src/bridge/messages/parentChanged.ts +14 -0
  257. package/src/bridge/messages/queryDataSource.ts +24 -0
  258. package/src/bridge/messages/queryDataSourceResult.ts +38 -0
  259. package/src/bridge/messages/ready.ts +41 -0
  260. package/src/bridge/messages/resize.ts +13 -0
  261. package/src/bridge/messages/sandboxToHost.ts +30 -0
  262. package/src/bridge/messages/themeChanged.ts +15 -0
  263. package/src/bridge/messages/updatePage.ts +22 -0
  264. package/src/bridge/messages/updatePageResult.ts +49 -0
  265. package/src/bridge/pages/page.ts +281 -0
  266. package/src/bridge/parent.ts +27 -0
  267. package/src/bridge/pendingRequests.ts +28 -0
  268. package/src/bridge/sandboxClient.ts +137 -0
  269. package/src/bridge/theme.ts +5 -0
  270. package/src/bridge/users/user.ts +31 -0
  271. package/src/css.d.ts +1 -0
  272. package/src/customBlock.ts +102 -0
  273. package/src/host/createCustomBlockHost.ts +392 -0
  274. package/src/host/lifecycle/initErrors.ts +132 -0
  275. package/src/host/lifecycle/ready.ts +36 -0
  276. package/src/host/lifecycle/types.ts +28 -0
  277. package/src/host/messages/invalidSandboxMessage.ts +38 -0
  278. package/src/host/messages/types.ts +67 -0
  279. package/src/host/queries/querySubscriptions.ts +52 -0
  280. package/src/host/queries/types.ts +16 -0
  281. package/src/host.ts +167 -0
  282. package/src/index.ts +115 -0
  283. package/src/init.ts +143 -0
  284. package/src/react/DebugMessageLog.tsx +30 -0
  285. package/src/react/NotionCustomBlock.css +110 -0
  286. package/src/react/NotionCustomBlock.tsx +151 -0
  287. package/src/react/index.ts +28 -0
  288. package/src/react/standalonePreview.ts +28 -0
  289. package/src/react/useCustomBlockAutoResize.ts +46 -0
  290. package/src/react/useCustomBlockInit.ts +91 -0
  291. package/src/react/useDataSource.ts +47 -0
  292. package/src/react/useHostState.ts +9 -0
  293. package/src/react/useRuntimeState.ts +85 -0
  294. package/src/types.ts +175 -0
  295. package/src/utils.ts +13 -0
  296. package/src/version.ts +8 -0
  297. package/vite-plugin/index.d.ts +46 -0
  298. package/vite-plugin/index.js +115 -0
@@ -0,0 +1,52 @@
1
+ import type { NotionDataSourceId } from "../../bridge/ids.js"
2
+ import type { QueryDataSourceMessage } from "../../bridge/messages/queryDataSource.js"
3
+ import type {
4
+ CustomBlockHostQueryDataSourceResult,
5
+ QuerySubscriptionState,
6
+ } from "./types.js"
7
+
8
+ export type QueryRefreshResult =
9
+ | {
10
+ status: "success"
11
+ requestId: string
12
+ snapshotId: string
13
+ response: CustomBlockHostQueryDataSourceResult
14
+ }
15
+ | { status: "missing" }
16
+
17
+ export class QuerySubscriptions {
18
+ private readonly latestByDataSourceId = new Map<
19
+ NotionDataSourceId,
20
+ QuerySubscriptionState
21
+ >()
22
+
23
+ track(message: QueryDataSourceMessage) {
24
+ this.latestByDataSourceId.set(message.dataSourceId, {
25
+ requestId: message.requestId,
26
+ snapshotId: message.snapshotId,
27
+ limit: message.limit,
28
+ })
29
+ }
30
+
31
+ resolveRefresh(args: {
32
+ dataSourceId: NotionDataSourceId
33
+ response: CustomBlockHostQueryDataSourceResult
34
+ }): QueryRefreshResult {
35
+ const queryState = this.latestByDataSourceId.get(args.dataSourceId)
36
+ if (!queryState) {
37
+ return { status: "missing" }
38
+ }
39
+ const items = args.response.items.slice(0, queryState.limit)
40
+ return {
41
+ status: "success",
42
+ requestId: queryState.requestId,
43
+ snapshotId: queryState.snapshotId,
44
+ response: {
45
+ items,
46
+ hasMore:
47
+ args.response.hasMore ?? args.response.items.length > items.length,
48
+ error: args.response.error,
49
+ },
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,16 @@
1
+ import type { QueryDataSourceMessage } from "../../bridge/messages/queryDataSource.js"
2
+ import type {
3
+ CustomBlockQueryDataSourceErrorInfo,
4
+ QueryDataSourceResultMessage,
5
+ } from "../../bridge/messages/queryDataSourceResult.js"
6
+
7
+ export type CustomBlockHostQueryDataSourceResult = {
8
+ items: QueryDataSourceResultMessage["items"]
9
+ hasMore?: boolean
10
+ error?: CustomBlockQueryDataSourceErrorInfo
11
+ }
12
+
13
+ export type QuerySubscriptionState = Pick<
14
+ QueryDataSourceMessage,
15
+ "requestId" | "snapshotId" | "limit"
16
+ >
package/src/host.ts ADDED
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Host-side entrypoint for `@notionhq/custom-blocks/host`.
3
+ *
4
+ * Re-exports the bridge valibot schemas and data-source binding types so
5
+ * anything implementing the host side of the bridge can validate inbound
6
+ * sandbox traffic and shape outbound traffic without reaching into private
7
+ * `bridge/*` paths.
8
+ *
9
+ * Nothing here is intended for use inside a sandboxed custom block; that
10
+ * surface lives in the default `@notionhq/custom-blocks` entrypoint.
11
+ */
12
+
13
+ export type {
14
+ NotionDataSourceBinding,
15
+ NotionDataSourceBindings,
16
+ } from "./bridge/dataSources/dataSource.js"
17
+ export {
18
+ notionDataSourceBindingSchema,
19
+ notionDataSourceBindingsSchema,
20
+ } from "./bridge/dataSources/dataSource.js"
21
+ export type { NotionDataSourcePageBridge } from "./bridge/dataSources/dataSourcePage.js"
22
+ export { notionDataSourcePageBridgeSchema } from "./bridge/dataSources/dataSourcePage.js"
23
+ export type {
24
+ CustomBlockDataSourceResolutionErrorCode,
25
+ CustomBlockDataSourceResolutionErrorInfo,
26
+ } from "./bridge/dataSources/errors.js"
27
+ export { customBlockDataSourceResolutionErrorCodeSchema } from "./bridge/dataSources/errors.js"
28
+ export type {
29
+ CustomBlockPropertyErrorCode,
30
+ CustomBlockPropertyErrorInfo,
31
+ } from "./bridge/dataSources/resolveProperty.js"
32
+ export { customBlockPropertyErrorCodeSchema } from "./bridge/dataSources/resolveProperty.js"
33
+ export type { CustomBlockErrorInfo } from "./bridge/errors.js"
34
+ export { customBlockErrorInfoSchema } from "./bridge/errors.js"
35
+ export {
36
+ notionBlockIdSchema,
37
+ notionDataSourceIdSchema,
38
+ notionPageIdSchema,
39
+ } from "./bridge/ids.js"
40
+ export { readIncomingType } from "./bridge/incomingType.js"
41
+ export type { CreatePageMessage } from "./bridge/messages/createPage.js"
42
+ export { createPageMessageSchema } from "./bridge/messages/createPage.js"
43
+ export type {
44
+ CreatePageResultMessage,
45
+ CustomBlockCreatePageErrorCode,
46
+ CustomBlockCreatePageErrorInfo,
47
+ } from "./bridge/messages/createPageResult.js"
48
+ export {
49
+ createPageResultMessageSchema,
50
+ customBlockCreatePageErrorCodeSchema,
51
+ customBlockCreatePageErrorInfoSchema,
52
+ } from "./bridge/messages/createPageResult.js"
53
+ export type { CurrentUserChangedMessage } from "./bridge/messages/currentUserChanged.js"
54
+ export { currentUserChangedMessageSchema } from "./bridge/messages/currentUserChanged.js"
55
+ export type { DataSourcesChangedMessage } from "./bridge/messages/dataSourcesChanged.js"
56
+ export { dataSourcesChangedMessageSchema } from "./bridge/messages/dataSourcesChanged.js"
57
+ export type {
58
+ CustomBlockGetPageErrorCode,
59
+ CustomBlockGetPageErrorInfo,
60
+ GetPageMessage,
61
+ GetPageResultMessage,
62
+ } from "./bridge/messages/getPage.js"
63
+ export {
64
+ customBlockGetPageErrorCodeSchema,
65
+ customBlockGetPageErrorInfoSchema,
66
+ getPageMessageSchema,
67
+ getPageResultMessageSchema,
68
+ } from "./bridge/messages/getPage.js"
69
+ export type {
70
+ CustomBlockGetUserErrorCode,
71
+ CustomBlockGetUserErrorInfo,
72
+ GetUserMessage,
73
+ GetUserResultMessage,
74
+ } from "./bridge/messages/getUser.js"
75
+ export {
76
+ customBlockGetUserErrorCodeSchema,
77
+ customBlockGetUserErrorInfoSchema,
78
+ getUserMessageSchema,
79
+ getUserResultMessageSchema,
80
+ } from "./bridge/messages/getUser.js"
81
+ export type { HostToSandboxMessage } from "./bridge/messages/hostToSandbox.js"
82
+ export { hostToSandboxMessageSchema } from "./bridge/messages/hostToSandbox.js"
83
+ export type {
84
+ CustomBlockInitErrorCode,
85
+ CustomBlockInitErrorInfo,
86
+ InitMessage,
87
+ } from "./bridge/messages/init.js"
88
+ export {
89
+ customBlockInitErrorCodeSchema,
90
+ customBlockInitErrorInfoSchema,
91
+ initMessageSchema,
92
+ } from "./bridge/messages/init.js"
93
+ export type { InvalidHostMessage } from "./bridge/messages/invalidHostMessage.js"
94
+ export { invalidHostMessageSchema } from "./bridge/messages/invalidHostMessage.js"
95
+ export type { InvalidSandboxMessage } from "./bridge/messages/invalidSandboxMessage.js"
96
+ export { invalidSandboxMessageSchema } from "./bridge/messages/invalidSandboxMessage.js"
97
+ export type {
98
+ CustomBlockListUsersErrorCode,
99
+ CustomBlockListUsersErrorInfo,
100
+ ListUsersMessage,
101
+ ListUsersResultMessage,
102
+ } from "./bridge/messages/listUsers.js"
103
+ export {
104
+ customBlockListUsersErrorCodeSchema,
105
+ customBlockListUsersErrorInfoSchema,
106
+ listUsersMessageSchema,
107
+ listUsersResultMessageSchema,
108
+ } from "./bridge/messages/listUsers.js"
109
+ export type { PageChangedMessage } from "./bridge/messages/pageChanged.js"
110
+ export { pageChangedMessageSchema } from "./bridge/messages/pageChanged.js"
111
+ export type { ParentChangedMessage } from "./bridge/messages/parentChanged.js"
112
+ export { parentChangedMessageSchema } from "./bridge/messages/parentChanged.js"
113
+ export type { QueryDataSourceMessage } from "./bridge/messages/queryDataSource.js"
114
+ export { queryDataSourceMessageSchema } from "./bridge/messages/queryDataSource.js"
115
+ export type {
116
+ CustomBlockQueryDataSourceErrorCode,
117
+ CustomBlockQueryDataSourceErrorInfo,
118
+ QueryDataSourceResultMessage,
119
+ } from "./bridge/messages/queryDataSourceResult.js"
120
+ export {
121
+ customBlockQueryDataSourceErrorCodeSchema,
122
+ customBlockQueryDataSourceErrorInfoSchema,
123
+ queryDataSourceResultMessageSchema,
124
+ } from "./bridge/messages/queryDataSourceResult.js"
125
+ export type { ReadyMessage } from "./bridge/messages/ready.js"
126
+ export { readyMessageSchema } from "./bridge/messages/ready.js"
127
+ export type { ResizeMessage } from "./bridge/messages/resize.js"
128
+ export { resizeMessageSchema } from "./bridge/messages/resize.js"
129
+ export type { SandboxToHostMessage } from "./bridge/messages/sandboxToHost.js"
130
+ export { sandboxToHostMessageSchema } from "./bridge/messages/sandboxToHost.js"
131
+ export type { ThemeChangedMessage } from "./bridge/messages/themeChanged.js"
132
+ export { themeChangedMessageSchema } from "./bridge/messages/themeChanged.js"
133
+ export type { UpdatePageMessage } from "./bridge/messages/updatePage.js"
134
+ export { updatePageMessageSchema } from "./bridge/messages/updatePage.js"
135
+ export type {
136
+ CustomBlockUpdatePageErrorCode,
137
+ CustomBlockUpdatePageErrorInfo,
138
+ UpdatePageResultMessage,
139
+ } from "./bridge/messages/updatePageResult.js"
140
+ export {
141
+ customBlockUpdatePageErrorCodeSchema,
142
+ customBlockUpdatePageErrorInfoSchema,
143
+ updatePageResultMessageSchema,
144
+ } from "./bridge/messages/updatePageResult.js"
145
+ export type { CustomBlockPage } from "./bridge/pages/page.js"
146
+ export { customBlockPageSchema } from "./bridge/pages/page.js"
147
+ export { notionParentSchema } from "./bridge/parent.js"
148
+ export {
149
+ type CustomBlockHostHandle,
150
+ type CustomBlockHostOptions,
151
+ createCustomBlockHost,
152
+ } from "./host/createCustomBlockHost.js"
153
+ export type {
154
+ CustomBlockHostDataSourcesPayload,
155
+ CustomBlockHostInitialDataSources,
156
+ CustomBlockHostInitialState,
157
+ } from "./host/lifecycle/types.js"
158
+ export type {
159
+ CustomBlockHostCreatePageResult,
160
+ CustomBlockHostGetPageResult,
161
+ CustomBlockHostGetUserResult,
162
+ CustomBlockHostHandlers,
163
+ CustomBlockHostListUsersResult,
164
+ CustomBlockHostLogDirection,
165
+ CustomBlockHostUpdatePageResult,
166
+ } from "./host/messages/types.js"
167
+ export type { CustomBlockHostQueryDataSourceResult } from "./host/queries/types.js"
package/src/index.ts ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Public entrypoint for `@notionhq/custom-blocks`.
3
+ *
4
+ * Everything re-exported here is part of the SDK's public API. Anything not
5
+ * re-exported is internal and may change without notice. Framework-neutral
6
+ * consumers should import from `@notionhq/custom-blocks`; React consumers
7
+ * should import hooks and components from `@notionhq/custom-blocks/react`.
8
+ */
9
+
10
+ export type {
11
+ NotionCollectionSchema,
12
+ NotionDataSource,
13
+ } from "./bridge/dataSources/dataSource.js"
14
+ export type {
15
+ NotionDataSourcePage,
16
+ NotionDataSourcePageUpdateInput,
17
+ NotionDataSourcePageUpdateResult,
18
+ } from "./bridge/dataSources/dataSourcePage.js"
19
+ export type { NotionDataSourceValue } from "./bridge/dataSources/dataSourceValue.js"
20
+ export type {
21
+ NotionDate,
22
+ NotionDateRange,
23
+ NotionDateReminder,
24
+ NotionDateTime,
25
+ NotionDateTimeRange,
26
+ NotionDateTimeReminder,
27
+ NotionDateValue,
28
+ NotionNoReminder,
29
+ NotionTimeReminder,
30
+ } from "./bridge/dataSources/dateValue.js"
31
+ export type {
32
+ CustomBlockDataSourceResolutionErrorCode,
33
+ CustomBlockDataSourceResolutionErrorInfo,
34
+ } from "./bridge/dataSources/errors.js"
35
+ export type {
36
+ NotionBuiltinPropertyId,
37
+ NotionDualProperty,
38
+ NotionPropertyColor,
39
+ NotionPropertyOption,
40
+ NotionPropertySchema,
41
+ NotionPropertyType,
42
+ NotionStatusGroup,
43
+ } from "./bridge/dataSources/propertySchema.js"
44
+ export {
45
+ NOTION_BUILTIN_PROPERTY_IDS,
46
+ NOTION_PROPERTY_TYPES,
47
+ } from "./bridge/dataSources/propertySchema.js"
48
+ export type { NotionRecordPointer } from "./bridge/dataSources/recordPointer.js"
49
+ export type {
50
+ CustomBlockPropertyErrorCode,
51
+ CustomBlockPropertyErrorInfo,
52
+ } from "./bridge/dataSources/resolveProperty.js"
53
+ export type { CustomBlockErrorInfo } from "./bridge/errors.js"
54
+ export type {
55
+ NotionBlockId,
56
+ NotionDataSourceId,
57
+ NotionSpaceId,
58
+ } from "./bridge/ids.js"
59
+ export type {
60
+ CustomBlockManifest,
61
+ ManifestDataSource,
62
+ ManifestIcon,
63
+ ManifestProperty,
64
+ } from "./bridge/manifest.js"
65
+ export type { NotionCreatePagePosition } from "./bridge/messages/createPage.js"
66
+ export type {
67
+ CustomBlockCreatePageErrorCode,
68
+ CustomBlockCreatePageErrorInfo,
69
+ } from "./bridge/messages/createPageResult.js"
70
+ export type {
71
+ CustomBlockGetPageErrorCode,
72
+ CustomBlockGetPageErrorInfo,
73
+ } from "./bridge/messages/getPage.js"
74
+ export type {
75
+ CustomBlockGetUserErrorCode,
76
+ CustomBlockGetUserErrorInfo,
77
+ } from "./bridge/messages/getUser.js"
78
+ export type {
79
+ CustomBlockInitErrorCode,
80
+ CustomBlockInitErrorInfo,
81
+ } from "./bridge/messages/init.js"
82
+ export { CustomBlockInitError } from "./bridge/messages/init.js"
83
+ export type {
84
+ CustomBlockListUsersErrorCode,
85
+ CustomBlockListUsersErrorInfo,
86
+ } from "./bridge/messages/listUsers.js"
87
+ export type {
88
+ CustomBlockQueryDataSourceErrorCode,
89
+ CustomBlockQueryDataSourceErrorInfo,
90
+ } from "./bridge/messages/queryDataSourceResult.js"
91
+ export type {
92
+ CustomBlockUpdatePageErrorCode,
93
+ CustomBlockUpdatePageErrorInfo,
94
+ } from "./bridge/messages/updatePageResult.js"
95
+ export type {
96
+ NotionPage,
97
+ NotionPageCover,
98
+ NotionPageIcon,
99
+ NotionPageId,
100
+ NotionPagePropertyInputMap,
101
+ NotionPagePropertyInputValue,
102
+ NotionPagePropertyValue,
103
+ NotionPagePropertyWriteMap,
104
+ } from "./bridge/pages/page.js"
105
+ export type { NotionParent } from "./bridge/parent.js"
106
+ export { pages, users } from "./bridge/sandboxClient.js"
107
+ export type { NotionTheme } from "./bridge/theme.js"
108
+ export { type CustomBlockState, customBlock } from "./customBlock.js"
109
+ export {
110
+ type CustomBlockInitial,
111
+ type InitCustomBlockOptions,
112
+ initCustomBlock,
113
+ NotInIframeError,
114
+ } from "./init.js"
115
+ export * from "./types.js"
package/src/init.ts ADDED
@@ -0,0 +1,143 @@
1
+ import type { NotionDataSource } from "./bridge/dataSources/dataSource.js"
2
+ import type { NotionBlockId } from "./bridge/ids.js"
3
+ import { loadManifest } from "./bridge/loadManifest.js"
4
+ import {
5
+ CustomBlockInitError,
6
+ type CustomBlockInitErrorCode,
7
+ type InitMessage,
8
+ } from "./bridge/messages/init.js"
9
+ import type { CustomBlockPage } from "./bridge/pages/page.js"
10
+ import type { NotionParent } from "./bridge/parent.js"
11
+ import { customBlockHost } from "./bridge/sandboxClient.js"
12
+ import type { NotionTheme } from "./bridge/theme.js"
13
+ import type { NotionUser } from "./bridge/users/user.js"
14
+
15
+ /**
16
+ * The payload sent by the host in the `init` message in response to the sandbox's `ready` message.
17
+ */
18
+ export type CustomBlockInitial = {
19
+ theme: NotionTheme
20
+ blockId: NotionBlockId
21
+ parent: NotionParent
22
+ page: CustomBlockPage
23
+ currentUser: NotionUser
24
+ dataSources: NotionDataSource[]
25
+ }
26
+
27
+ /**
28
+ * Error thrown when the SDK is loaded in a top-level standalone window with no parent frame.
29
+ * `postMessage` would just hit the same window and the handshake can never complete.
30
+ * `<NotionCustomBlock>` catches this specifically and falls back to a standalone preview with a
31
+ * warning banner. Direct callers can `instanceof` it to apply their own policy.
32
+ */
33
+ export class NotInIframeError extends Error {
34
+ constructor(message: string = NOT_IN_IFRAME_MESSAGE) {
35
+ super(message)
36
+ this.name = "NotInIframeError"
37
+ this.code = "not_in_iframe"
38
+ this.isRetryable = false
39
+ }
40
+
41
+ code: CustomBlockInitErrorCode
42
+ isRetryable: boolean
43
+ }
44
+
45
+ /**
46
+ * Options for {@link initCustomBlock}.
47
+ */
48
+ export type InitCustomBlockOptions = {
49
+ /**
50
+ * How long to wait for the host's `init` response before rejecting with an error.
51
+ *
52
+ * @default 15000 - Intentionally longer than Notion's 10s host-dependency watchdog
53
+ * so host-owned init errors can arrive before the SDK's generic fallback appears.
54
+ */
55
+ timeoutMs?: number
56
+ }
57
+
58
+ const DEFAULT_INIT_TIMEOUT_MS = 15_000
59
+
60
+ const NOT_IN_IFRAME_MESSAGE =
61
+ "<NotionCustomBlock> only works inside an iframe — use the dev shell or deploy to Notion."
62
+
63
+ let initPromise: Promise<CustomBlockInitial> | undefined
64
+
65
+ /**
66
+ * Performs the SDK <-> host handshake: loads `custom_blocks.json`, posts
67
+ * `ready`, then awaits the host's `init` message. Resolves with that payload.
68
+ *
69
+ * Rejects with a `CustomBlockInitError` if the host doesn't respond inside `timeoutMs`.
70
+ *
71
+ * Idempotent: subsequent calls return the same promise as the first and ignore any new options.
72
+ * Mount your React tree (or call any SDK hook / `customBlock.subscribe`) only after the
73
+ * returned promise resolves.
74
+ */
75
+ export function initCustomBlock(
76
+ opts: InitCustomBlockOptions = {},
77
+ ): Promise<CustomBlockInitial> {
78
+ if (initPromise === undefined) {
79
+ initPromise = (async () => {
80
+ // Fail fast with a typed error when rendered as a standalone tab and not in a parent frame.
81
+ // Otherwise, it would eventually hit the timeout, since `postMessage` to `window.parent`
82
+ // would just hit the same window and never arrive.
83
+ if (typeof window !== "undefined" && window.parent === window) {
84
+ throw new NotInIframeError()
85
+ }
86
+
87
+ // Load the manifest and send it to the host.
88
+ const manifestResult = await loadManifest()
89
+ customBlockHost.sendReady(manifestResult)
90
+
91
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_INIT_TIMEOUT_MS
92
+ let message: InitMessage
93
+ try {
94
+ message = await customBlockHost.awaitInit(
95
+ AbortSignal.timeout(timeoutMs),
96
+ )
97
+ } catch (error) {
98
+ if (isTimeoutError(error)) {
99
+ throw new CustomBlockInitError({
100
+ code: "init_timeout",
101
+ message: "Host did not respond to init before the timeout.",
102
+ isRetryable: true,
103
+ })
104
+ }
105
+ throw error
106
+ }
107
+ if (message.status === "error") {
108
+ console.error(
109
+ `[notion-custom-sdk] host reported init error (${message.error.code}): ${message.error.message}`,
110
+ )
111
+ throw new CustomBlockInitError(message.error)
112
+ }
113
+
114
+ const hostState = customBlockHost.getState()
115
+ if (hostState.status !== "initialized") {
116
+ throw new CustomBlockInitError({
117
+ code: "context_unavailable",
118
+ message: "Host block payload is unavailable.",
119
+ isRetryable: true,
120
+ })
121
+ }
122
+
123
+ return {
124
+ theme: message.theme,
125
+ blockId: hostState.blockId,
126
+ parent: hostState.parent,
127
+ page: hostState.page,
128
+ currentUser: message.currentUser,
129
+ dataSources: hostState.dataSources,
130
+ }
131
+ })()
132
+ }
133
+ return initPromise
134
+ }
135
+
136
+ function isTimeoutError(error: unknown): boolean {
137
+ return (
138
+ typeof error === "object" &&
139
+ error !== null &&
140
+ "name" in error &&
141
+ (error.name === "TimeoutError" || error.name === "AbortError")
142
+ )
143
+ }
@@ -0,0 +1,30 @@
1
+ import { useSyncExternalStore } from "react"
2
+ import { messageLog } from "../bridge/sandboxClient.js"
3
+
4
+ export function DebugMessageLog() {
5
+ const log = useSyncExternalStore(messageLog.subscribe, messageLog.getSnapshot)
6
+ const text = log
7
+ .map(
8
+ entry =>
9
+ `[${entry.timestamp}] ${entry.direction}: ${JSON.stringify(entry.data)}`,
10
+ )
11
+ .join("\n")
12
+ return (
13
+ <pre data-testid="debug-message-log" style={DEBUG_PRE_STYLE}>
14
+ {text || "(no messages yet)"}
15
+ </pre>
16
+ )
17
+ }
18
+
19
+ const DEBUG_PRE_STYLE = {
20
+ margin: 0,
21
+ padding: "8px 12px",
22
+ fontSize: 12,
23
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
24
+ lineHeight: 1.5,
25
+ whiteSpace: "pre-wrap" as const,
26
+ wordBreak: "break-all" as const,
27
+ userSelect: "text" as const,
28
+ background: "#1e1e1e",
29
+ color: "#d4d4d4",
30
+ }
@@ -0,0 +1,110 @@
1
+ .ncblock-standalone-banner {
2
+ --ncblock-standalone-banner-background: #fff8e1;
3
+ --ncblock-standalone-banner-border: #f0d77b;
4
+ --ncblock-standalone-banner-text: #5d4200;
5
+
6
+ padding: 8px 12px;
7
+ background: var(--ncblock-standalone-banner-background);
8
+ color: var(--ncblock-standalone-banner-text);
9
+ border-bottom: 1px solid var(--ncblock-standalone-banner-border);
10
+ font-size: 13px;
11
+ font-family: system-ui, sans-serif;
12
+ line-height: 1.4;
13
+ }
14
+
15
+ .ncblock-default-init-error {
16
+ --ncblock-init-error-background: #f7f7f5;
17
+ --ncblock-init-error-card-background: #ffffff;
18
+ --ncblock-init-error-border: #e5e5e1;
19
+ --ncblock-init-error-text: #1f1f1d;
20
+ --ncblock-init-error-muted-text: #5f5e5b;
21
+ --ncblock-init-error-eyebrow-text: #787774;
22
+ --ncblock-init-error-pre-background: #f1f1ef;
23
+ --ncblock-init-error-pre-text: #37352f;
24
+ --ncblock-init-error-shadow: rgba(0, 0, 0, 0.08);
25
+
26
+ box-sizing: border-box;
27
+ min-height: 240px;
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ padding: 24px;
32
+ background: var(--ncblock-init-error-background);
33
+ color: var(--ncblock-init-error-text);
34
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
35
+ color-scheme: light;
36
+ }
37
+
38
+ .ncblock-default-init-error__card {
39
+ box-sizing: border-box;
40
+ width: 100%;
41
+ max-width: 420px;
42
+ padding: 20px;
43
+ border: 1px solid var(--ncblock-init-error-border);
44
+ border-radius: 12px;
45
+ background: var(--ncblock-init-error-card-background);
46
+ box-shadow: 0 8px 24px var(--ncblock-init-error-shadow);
47
+ }
48
+
49
+ .ncblock-default-init-error__eyebrow {
50
+ margin-bottom: 8px;
51
+ font-size: 11px;
52
+ font-weight: 600;
53
+ letter-spacing: 0.08em;
54
+ text-transform: uppercase;
55
+ color: var(--ncblock-init-error-eyebrow-text);
56
+ }
57
+
58
+ .ncblock-default-init-error__title {
59
+ margin: 0;
60
+ font-size: 18px;
61
+ line-height: 1.3;
62
+ font-weight: 650;
63
+ }
64
+
65
+ .ncblock-default-init-error__body {
66
+ margin: 8px 0 0;
67
+ font-size: 14px;
68
+ line-height: 1.5;
69
+ color: var(--ncblock-init-error-muted-text);
70
+ }
71
+
72
+ .ncblock-default-init-error__details {
73
+ margin-top: 14px;
74
+ font-size: 12px;
75
+ color: var(--ncblock-init-error-muted-text);
76
+ }
77
+
78
+ .ncblock-default-init-error__pre {
79
+ margin: 8px 0 0;
80
+ padding: 10px;
81
+ overflow: auto;
82
+ border-radius: 8px;
83
+ background: var(--ncblock-init-error-pre-background);
84
+ color: var(--ncblock-init-error-pre-text);
85
+ font-size: 12px;
86
+ line-height: 1.4;
87
+ white-space: pre-wrap;
88
+ }
89
+
90
+ @media (prefers-color-scheme: dark) {
91
+ .ncblock-standalone-banner {
92
+ --ncblock-standalone-banner-background: #3b2f0b;
93
+ --ncblock-standalone-banner-border: #6f5713;
94
+ --ncblock-standalone-banner-text: #f5d36c;
95
+ }
96
+
97
+ .ncblock-default-init-error {
98
+ --ncblock-init-error-background: #191918;
99
+ --ncblock-init-error-card-background: #20201f;
100
+ --ncblock-init-error-border: #373633;
101
+ --ncblock-init-error-text: #f1f1ef;
102
+ --ncblock-init-error-muted-text: #b9b8b3;
103
+ --ncblock-init-error-eyebrow-text: #9b9a97;
104
+ --ncblock-init-error-pre-background: #2a2a28;
105
+ --ncblock-init-error-pre-text: #e8e8e4;
106
+ --ncblock-init-error-shadow: rgba(0, 0, 0, 0.35);
107
+
108
+ color-scheme: dark;
109
+ }
110
+ }