@notionhq/custom-blocks 0.1.33 → 0.1.35

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 (36) hide show
  1. package/dist/bridge/SandboxBridge.d.ts +3 -1
  2. package/dist/bridge/SandboxBridge.d.ts.map +1 -1
  3. package/dist/bridge/SandboxBridge.js +55 -47
  4. package/dist/bridge/dataSources/query.d.ts +27 -0
  5. package/dist/bridge/dataSources/query.d.ts.map +1 -0
  6. package/dist/bridge/dataSources/query.js +512 -0
  7. package/dist/bridge/hostState.d.ts +4 -3
  8. package/dist/bridge/hostState.d.ts.map +1 -1
  9. package/dist/bridge/hostState.js +7 -3
  10. package/dist/bridge/sandboxClient.d.ts +4 -2
  11. package/dist/bridge/sandboxClient.d.ts.map +1 -1
  12. package/dist/bridge/sandboxClient.js +10 -4
  13. package/dist/protocol/dataSources/propertySchema.d.ts +7 -0
  14. package/dist/protocol/dataSources/propertySchema.d.ts.map +1 -1
  15. package/dist/protocol/dataSources/propertySchema.js +17 -0
  16. package/dist/protocol/messages/queryDataSource.d.ts +970 -0
  17. package/dist/protocol/messages/queryDataSource.d.ts.map +1 -1
  18. package/dist/protocol/messages/queryDataSource.js +108 -0
  19. package/dist/protocol/messages/queryDataSourceResult.d.ts +1 -1
  20. package/dist/protocol/messages/queryDataSourceResult.d.ts.map +1 -1
  21. package/dist/protocol/messages/sandboxToHost.d.ts +353 -0
  22. package/dist/protocol/messages/sandboxToHost.d.ts.map +1 -1
  23. package/dist/react/useDataSource.d.ts +1 -1
  24. package/dist/react/useDataSource.d.ts.map +1 -1
  25. package/dist/react/useDataSource.js +11 -6
  26. package/dist/types.d.ts +52 -0
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/version.js +1 -1
  29. package/docs/data-sources.md +51 -3
  30. package/package.json +1 -1
  31. package/src/bridge/SandboxBridge.ts +66 -57
  32. package/src/bridge/dataSources/query.ts +694 -0
  33. package/src/bridge/hostState.ts +11 -3
  34. package/src/bridge/sandboxClient.ts +20 -4
  35. package/src/react/useDataSource.ts +17 -6
  36. package/src/types.ts +55 -0
@@ -41,17 +41,21 @@ export type InitializedHostState = {
41
41
  }
42
42
 
43
43
  export type DataSourceQueryState = {
44
+ dataSourceKey: string
44
45
  /** Latest pages from the host as parsed from the bridge. `propertiesByKey` is derived lazily. */
45
46
  items: NotionDataSourcePageBridge[]
46
47
  isLoading: boolean
47
48
  hasMore: boolean
48
49
  error?: CustomBlockQueryDataSourceErrorInfo
49
- subscriptionId?: string
50
50
  latestLimit?: number
51
+ latestQueryIdentity?: string
51
52
  }
52
53
 
53
- export function createEmptyDataSourceQueryState(): DataSourceQueryState {
54
+ export function createEmptyDataSourceQueryState(
55
+ dataSourceKey: string,
56
+ ): DataSourceQueryState {
54
57
  return {
58
+ dataSourceKey,
55
59
  items: [],
56
60
  isLoading: false,
57
61
  hasMore: false,
@@ -97,6 +101,7 @@ export type UpdateDataSourcePageFn = (args: {
97
101
  export function getDataSourceQueryView(
98
102
  hostState: CustomBlockHostState,
99
103
  key: string,
104
+ subscriptionId: string,
100
105
  updateDataSourcePage: UpdateDataSourcePageFn,
101
106
  ): DataSourceQueryView {
102
107
  if (hostState.status !== "initialized") {
@@ -104,8 +109,11 @@ export function getDataSourceQueryView(
104
109
  }
105
110
 
106
111
  const dataSource = hostState.dataSources.find(entry => entry.key === key)
112
+ const subscriptionState = hostState.dataSourceState[subscriptionId]
107
113
  const queryState =
108
- hostState.dataSourceState[key] ?? createEmptyDataSourceQueryState()
114
+ subscriptionState?.dataSourceKey === key
115
+ ? subscriptionState
116
+ : createEmptyDataSourceQueryState(key)
109
117
 
110
118
  if (dataSource === undefined) {
111
119
  return {
@@ -68,16 +68,32 @@ export const customBlockHost = {
68
68
  }
69
69
 
70
70
  export const customBlockDataSources = {
71
- query: (key: string, options?: UseDataSourceOptions) => {
72
- getBridge().queryDataSource(key, options)
71
+ createSubscriptionId: () => {
72
+ return getBridge().createDataSourceSubscriptionId()
73
+ },
74
+
75
+ query: (
76
+ subscriptionId: string,
77
+ key: string,
78
+ options?: UseDataSourceOptions,
79
+ ) => {
80
+ getBridge().queryDataSource(subscriptionId, key, options)
81
+ },
82
+
83
+ release: (subscriptionId: string) => {
84
+ getBridge().releaseDataSourceSubscription(subscriptionId)
73
85
  },
74
86
 
75
87
  getView: (
76
88
  hostState: CustomBlockHostState,
77
89
  key: string,
90
+ subscriptionId: string,
78
91
  ): DataSourceQueryView => {
79
- return getDataSourceQueryViewWithBridge(hostState, key, args =>
80
- getBridge().updateDataSourcePage(args),
92
+ return getDataSourceQueryViewWithBridge(
93
+ hostState,
94
+ key,
95
+ subscriptionId,
96
+ args => getBridge().updateDataSourcePage(args),
81
97
  )
82
98
  },
83
99
  }
@@ -1,4 +1,5 @@
1
- import { useEffect } from "react"
1
+ import { useEffect, useState } from "react"
2
+ import { getDataSourceQueryOptionsIdentity } from "../bridge/dataSources/query.js"
2
3
  import { customBlockDataSources } from "../bridge/sandboxClient.js"
3
4
  import type { UseDataSourceOptions, UseDataSourceResult } from "../types.js"
4
5
  import { useCustomBlockHost } from "./useHostState.js"
@@ -8,7 +9,7 @@ import { useCustomBlockHost } from "./useHostState.js"
8
9
  *
9
10
  * @param key - The semantic data source key the block is wired to (e.g. `"people"`).
10
11
  * @param options - Optional live snapshot options. `limit` defaults to 20 and
11
- * is capped at 999.
12
+ * is capped at 999. `sorts` are applied in array order.
12
13
  *
13
14
  * @example
14
15
  * const { items, isLoading, hasMore, error } = useDataSource("default", { limit: 25 })
@@ -18,7 +19,10 @@ export function useDataSource(
18
19
  options?: UseDataSourceOptions,
19
20
  ): UseDataSourceResult {
20
21
  const host = useCustomBlockHost()
21
- const limit = options?.limit
22
+ const [subscriptionId] = useState(() =>
23
+ customBlockDataSources.createSubscriptionId(),
24
+ )
25
+ const optionsIdentity = getDataSourceQueryOptionsIdentity(options)
22
26
  const matchingDataSource =
23
27
  host.status === "initialized"
24
28
  ? host.dataSources.find(dataSource => dataSource.key === key)
@@ -30,10 +34,17 @@ export function useDataSource(
30
34
  return
31
35
  }
32
36
 
33
- customBlockDataSources.query(key, { limit })
34
- }, [matchingDataSource, isInitialized, key, limit])
37
+ customBlockDataSources.query(subscriptionId, key, options)
38
+ }, [matchingDataSource, isInitialized, key, optionsIdentity, subscriptionId])
35
39
 
36
- const view = customBlockDataSources.getView(host, key)
40
+ useEffect(
41
+ () => () => {
42
+ customBlockDataSources.release(subscriptionId)
43
+ },
44
+ [subscriptionId],
45
+ )
46
+
47
+ const view = customBlockDataSources.getView(host, key, subscriptionId)
37
48
 
38
49
  return {
39
50
  items: view.items,
package/src/types.ts CHANGED
@@ -24,6 +24,14 @@ import type {
24
24
  ListUsersMessage,
25
25
  ListUsersResultMessage,
26
26
  } from "@notionhq/custom-blocks-protocol/messages/listUsers.js"
27
+ import type {
28
+ CustomBlockCheckboxFilterOperator,
29
+ CustomBlockContainsFilterOperator,
30
+ CustomBlockDateFilterOperator,
31
+ CustomBlockNumberFilterOperator,
32
+ CustomBlockOptionFilterOperator,
33
+ CustomBlockTextFilterOperator,
34
+ } from "@notionhq/custom-blocks-protocol/messages/queryDataSource.js"
27
35
  import type { CustomBlockQueryDataSourceErrorInfo } from "@notionhq/custom-blocks-protocol/messages/queryDataSourceResult.js"
28
36
  import type { UpdatePageMessage } from "@notionhq/custom-blocks-protocol/messages/updatePage.js"
29
37
  import type {
@@ -116,6 +124,44 @@ export type NotionDataSourcePageUpdateInput = NotionDataSourcePageUpdateArgs
116
124
  */
117
125
  export type NotionDataSourcePageUpdateResult = UpdatePageResult
118
126
 
127
+ export type NotionDataSourceTextFilterOperator = CustomBlockTextFilterOperator
128
+ export type NotionDataSourceNumberFilterOperator =
129
+ CustomBlockNumberFilterOperator
130
+ export type NotionDataSourceCheckboxFilterOperator =
131
+ CustomBlockCheckboxFilterOperator
132
+ export type NotionDataSourceOptionFilterOperator =
133
+ CustomBlockOptionFilterOperator
134
+ export type NotionDataSourceContainsFilterOperator =
135
+ CustomBlockContainsFilterOperator
136
+ export type NotionDataSourceDateFilterOperator = CustomBlockDateFilterOperator
137
+
138
+ export type NotionDataSourcePropertyAddress =
139
+ | { key: string; propertyId?: never }
140
+ | { propertyId: string; key?: never }
141
+
142
+ export type NotionDataSourcePropertyFilter = NotionDataSourcePropertyAddress &
143
+ (
144
+ | { title: NotionDataSourceTextFilterOperator }
145
+ | { rich_text: NotionDataSourceTextFilterOperator }
146
+ | { url: NotionDataSourceTextFilterOperator }
147
+ | { email: NotionDataSourceTextFilterOperator }
148
+ | { phone_number: NotionDataSourceTextFilterOperator }
149
+ | { number: NotionDataSourceNumberFilterOperator }
150
+ | { checkbox: NotionDataSourceCheckboxFilterOperator }
151
+ | { select: NotionDataSourceOptionFilterOperator }
152
+ | { multi_select: NotionDataSourceContainsFilterOperator }
153
+ | { status: NotionDataSourceOptionFilterOperator }
154
+ | { date: NotionDataSourceDateFilterOperator }
155
+ )
156
+
157
+ export type NotionDataSourceSort = NotionDataSourcePropertyAddress & {
158
+ direction: "ascending" | "descending"
159
+ }
160
+
161
+ export type NotionDataSourceFilter =
162
+ | NotionDataSourcePropertyFilter
163
+ | { and: NotionDataSourcePropertyFilter[] }
164
+
119
165
  /**
120
166
  * Return shape of `useDataSource`.
121
167
  *
@@ -157,6 +203,15 @@ export type UseDataSourceOptions = {
157
203
  * Maximum number of rows to request from the host. Defaults to 20.
158
204
  */
159
205
  limit?: number
206
+ /**
207
+ * Optional property filter. The SDK resolves semantic property keys before
208
+ * it sends the query to the host.
209
+ */
210
+ filter?: NotionDataSourceFilter
211
+ /**
212
+ * Optional property sorts. The host applies them in array order.
213
+ */
214
+ sorts?: NotionDataSourceSort[]
160
215
  }
161
216
 
162
217
  /**