@sqlrooms/deck 0.29.0-rc.10

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 (251) hide show
  1. package/LICENSE.md +10 -0
  2. package/README.md +654 -0
  3. package/dist/BlockMapSettings.d.ts +3 -0
  4. package/dist/BlockMapSettings.d.ts.map +1 -0
  5. package/dist/BlockMapSettings.js +57 -0
  6. package/dist/BlockMapSettings.js.map +1 -0
  7. package/dist/DashboardMapSettings.d.ts +7 -0
  8. package/dist/DashboardMapSettings.d.ts.map +1 -0
  9. package/dist/DashboardMapSettings.js +52 -0
  10. package/dist/DashboardMapSettings.js.map +1 -0
  11. package/dist/DeckJsonMap.d.ts +4 -0
  12. package/dist/DeckJsonMap.d.ts.map +1 -0
  13. package/dist/DeckJsonMap.js +370 -0
  14. package/dist/DeckJsonMap.js.map +1 -0
  15. package/dist/DeckJsonMapSpec.d.ts +7617 -0
  16. package/dist/DeckJsonMapSpec.d.ts.map +1 -0
  17. package/dist/DeckJsonMapSpec.js +82 -0
  18. package/dist/DeckJsonMapSpec.js.map +1 -0
  19. package/dist/DeckMapDefaultStylesProvider.d.ts +28 -0
  20. package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -0
  21. package/dist/DeckMapDefaultStylesProvider.js +23 -0
  22. package/dist/DeckMapDefaultStylesProvider.js.map +1 -0
  23. package/dist/DeckMapSurface.d.ts +39 -0
  24. package/dist/DeckMapSurface.d.ts.map +1 -0
  25. package/dist/DeckMapSurface.js +137 -0
  26. package/dist/DeckMapSurface.js.map +1 -0
  27. package/dist/DeckMapsSlice.d.ts +99 -0
  28. package/dist/DeckMapsSlice.d.ts.map +1 -0
  29. package/dist/DeckMapsSlice.js +89 -0
  30. package/dist/DeckMapsSlice.js.map +1 -0
  31. package/dist/MapSettings.d.ts +16 -0
  32. package/dist/MapSettings.d.ts.map +1 -0
  33. package/dist/MapSettings.js +292 -0
  34. package/dist/MapSettings.js.map +1 -0
  35. package/dist/MapSettingsControls.d.ts +40 -0
  36. package/dist/MapSettingsControls.d.ts.map +1 -0
  37. package/dist/MapSettingsControls.js +54 -0
  38. package/dist/MapSettingsControls.js.map +1 -0
  39. package/dist/ai.d.ts +261 -0
  40. package/dist/ai.d.ts.map +1 -0
  41. package/dist/ai.js +392 -0
  42. package/dist/ai.js.map +1 -0
  43. package/dist/block.d.ts +21 -0
  44. package/dist/block.d.ts.map +1 -0
  45. package/dist/block.js +105 -0
  46. package/dist/block.js.map +1 -0
  47. package/dist/blockDocumentRegistration.d.ts +45 -0
  48. package/dist/blockDocumentRegistration.d.ts.map +1 -0
  49. package/dist/blockDocumentRegistration.js +68 -0
  50. package/dist/blockDocumentRegistration.js.map +1 -0
  51. package/dist/createDeckJsonSpecFromDatasets.d.ts +11 -0
  52. package/dist/createDeckJsonSpecFromDatasets.d.ts.map +1 -0
  53. package/dist/createDeckJsonSpecFromDatasets.js +85 -0
  54. package/dist/createDeckJsonSpecFromDatasets.js.map +1 -0
  55. package/dist/createOrUpdateDeckMapResource.d.ts +81 -0
  56. package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -0
  57. package/dist/createOrUpdateDeckMapResource.js +82 -0
  58. package/dist/createOrUpdateDeckMapResource.js.map +1 -0
  59. package/dist/dashboard.d.ts +6 -0
  60. package/dist/dashboard.d.ts.map +1 -0
  61. package/dist/dashboard.js +337 -0
  62. package/dist/dashboard.js.map +1 -0
  63. package/dist/dashboardConfig.d.ts +25 -0
  64. package/dist/dashboardConfig.d.ts.map +1 -0
  65. package/dist/dashboardConfig.js +82 -0
  66. package/dist/dashboardConfig.js.map +1 -0
  67. package/dist/dashboardIntegration.d.ts +3 -0
  68. package/dist/dashboardIntegration.d.ts.map +1 -0
  69. package/dist/dashboardIntegration.js +16 -0
  70. package/dist/dashboardIntegration.js.map +1 -0
  71. package/dist/datasetSourceUtils.d.ts +16 -0
  72. package/dist/datasetSourceUtils.d.ts.map +1 -0
  73. package/dist/datasetSourceUtils.js +25 -0
  74. package/dist/datasetSourceUtils.js.map +1 -0
  75. package/dist/datasets/PreparedDatasetStore.d.ts +120 -0
  76. package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -0
  77. package/dist/datasets/PreparedDatasetStore.js +268 -0
  78. package/dist/datasets/PreparedDatasetStore.js.map +1 -0
  79. package/dist/datasets/helpers.d.ts +57 -0
  80. package/dist/datasets/helpers.d.ts.map +1 -0
  81. package/dist/datasets/helpers.js +155 -0
  82. package/dist/datasets/helpers.js.map +1 -0
  83. package/dist/datasets/normalizeDatasets.d.ts +11 -0
  84. package/dist/datasets/normalizeDatasets.d.ts.map +1 -0
  85. package/dist/datasets/normalizeDatasets.js +50 -0
  86. package/dist/datasets/normalizeDatasets.js.map +1 -0
  87. package/dist/datasets/tableAdapter.d.ts +11 -0
  88. package/dist/datasets/tableAdapter.d.ts.map +1 -0
  89. package/dist/datasets/tableAdapter.js +11 -0
  90. package/dist/datasets/tableAdapter.js.map +1 -0
  91. package/dist/datasets/tableDatasetSql.d.ts +16 -0
  92. package/dist/datasets/tableDatasetSql.d.ts.map +1 -0
  93. package/dist/datasets/tableDatasetSql.js +49 -0
  94. package/dist/datasets/tableDatasetSql.js.map +1 -0
  95. package/dist/datasets/types.d.ts +40 -0
  96. package/dist/datasets/types.d.ts.map +1 -0
  97. package/dist/datasets/types.js +2 -0
  98. package/dist/datasets/types.js.map +1 -0
  99. package/dist/datasets/usePreparedDatasetStates.d.ts +16 -0
  100. package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -0
  101. package/dist/datasets/usePreparedDatasetStates.js +59 -0
  102. package/dist/datasets/usePreparedDatasetStates.js.map +1 -0
  103. package/dist/index.d.ts +34 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +27 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/json/aggregateWaypoints.d.ts +14 -0
  108. package/dist/json/aggregateWaypoints.d.ts.map +1 -0
  109. package/dist/json/aggregateWaypoints.js +190 -0
  110. package/dist/json/aggregateWaypoints.js.map +1 -0
  111. package/dist/json/colorScaleFunction.d.ts +27 -0
  112. package/dist/json/colorScaleFunction.d.ts.map +1 -0
  113. package/dist/json/colorScaleFunction.js +46 -0
  114. package/dist/json/colorScaleFunction.js.map +1 -0
  115. package/dist/json/compileColorScale.d.ts +12 -0
  116. package/dist/json/compileColorScale.d.ts.map +1 -0
  117. package/dist/json/compileColorScale.js +125 -0
  118. package/dist/json/compileColorScale.js.map +1 -0
  119. package/dist/json/compileGeoArrowAccessor.d.ts +18 -0
  120. package/dist/json/compileGeoArrowAccessor.d.ts.map +1 -0
  121. package/dist/json/compileGeoArrowAccessor.js +129 -0
  122. package/dist/json/compileGeoArrowAccessor.js.map +1 -0
  123. package/dist/json/createDeckJsonConfiguration.d.ts +9 -0
  124. package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -0
  125. package/dist/json/createDeckJsonConfiguration.js +315 -0
  126. package/dist/json/createDeckJsonConfiguration.js.map +1 -0
  127. package/dist/json/defaultClasses.d.ts +12 -0
  128. package/dist/json/defaultClasses.d.ts.map +1 -0
  129. package/dist/json/defaultClasses.js +35 -0
  130. package/dist/json/defaultClasses.js.map +1 -0
  131. package/dist/json/extractColorScaleLegends.d.ts +8 -0
  132. package/dist/json/extractColorScaleLegends.d.ts.map +1 -0
  133. package/dist/json/extractColorScaleLegends.js +86 -0
  134. package/dist/json/extractColorScaleLegends.js.map +1 -0
  135. package/dist/json/heatmapDefaults.d.ts +8 -0
  136. package/dist/json/heatmapDefaults.d.ts.map +1 -0
  137. package/dist/json/heatmapDefaults.js +14 -0
  138. package/dist/json/heatmapDefaults.js.map +1 -0
  139. package/dist/json/layerCompatibility.d.ts +21 -0
  140. package/dist/json/layerCompatibility.d.ts.map +1 -0
  141. package/dist/json/layerCompatibility.js +168 -0
  142. package/dist/json/layerCompatibility.js.map +1 -0
  143. package/dist/json/layerConfig.d.ts +14 -0
  144. package/dist/json/layerConfig.d.ts.map +1 -0
  145. package/dist/json/layerConfig.js +54 -0
  146. package/dist/json/layerConfig.js.map +1 -0
  147. package/dist/json/layers/DeckColumnLayer.d.ts +10 -0
  148. package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
  149. package/dist/json/layers/DeckColumnLayer.js +26 -0
  150. package/dist/json/layers/DeckColumnLayer.js.map +1 -0
  151. package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
  152. package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
  153. package/dist/json/layers/DeckH3HexagonLayer.js +118 -0
  154. package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
  155. package/dist/json/layers/DeckTripsLayer.d.ts +46 -0
  156. package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
  157. package/dist/json/layers/DeckTripsLayer.js +170 -0
  158. package/dist/json/layers/DeckTripsLayer.js.map +1 -0
  159. package/dist/json/layers/createTableToRecordBatchAdapter.d.ts +20 -0
  160. package/dist/json/layers/createTableToRecordBatchAdapter.d.ts.map +1 -0
  161. package/dist/json/layers/createTableToRecordBatchAdapter.js +81 -0
  162. package/dist/json/layers/createTableToRecordBatchAdapter.js.map +1 -0
  163. package/dist/json/layers/index.d.ts +5 -0
  164. package/dist/json/layers/index.d.ts.map +1 -0
  165. package/dist/json/layers/index.js +5 -0
  166. package/dist/json/layers/index.js.map +1 -0
  167. package/dist/json/rewriteGeoArrowAccessors.d.ts +7 -0
  168. package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -0
  169. package/dist/json/rewriteGeoArrowAccessors.js +55 -0
  170. package/dist/json/rewriteGeoArrowAccessors.js.map +1 -0
  171. package/dist/mapAiConfig.d.ts +111 -0
  172. package/dist/mapAiConfig.d.ts.map +1 -0
  173. package/dist/mapAiConfig.js +69 -0
  174. package/dist/mapAiConfig.js.map +1 -0
  175. package/dist/mapConfig.d.ts +73 -0
  176. package/dist/mapConfig.d.ts.map +1 -0
  177. package/dist/mapConfig.js +47 -0
  178. package/dist/mapConfig.js.map +1 -0
  179. package/dist/mapConfigUtils.d.ts +111 -0
  180. package/dist/mapConfigUtils.d.ts.map +1 -0
  181. package/dist/mapConfigUtils.js +502 -0
  182. package/dist/mapConfigUtils.js.map +1 -0
  183. package/dist/mapDataPolicy.d.ts +9 -0
  184. package/dist/mapDataPolicy.d.ts.map +1 -0
  185. package/dist/mapDataPolicy.js +25 -0
  186. package/dist/mapDataPolicy.js.map +1 -0
  187. package/dist/mapFit.d.ts +62 -0
  188. package/dist/mapFit.d.ts.map +1 -0
  189. package/dist/mapFit.js +325 -0
  190. package/dist/mapFit.js.map +1 -0
  191. package/dist/mapLayerConfigUtils.d.ts +54 -0
  192. package/dist/mapLayerConfigUtils.d.ts.map +1 -0
  193. package/dist/mapLayerConfigUtils.js +296 -0
  194. package/dist/mapLayerConfigUtils.js.map +1 -0
  195. package/dist/mapResourceAuthoring.d.ts +40 -0
  196. package/dist/mapResourceAuthoring.d.ts.map +1 -0
  197. package/dist/mapResourceAuthoring.js +266 -0
  198. package/dist/mapResourceAuthoring.js.map +1 -0
  199. package/dist/mosaic.d.ts +9 -0
  200. package/dist/mosaic.d.ts.map +1 -0
  201. package/dist/mosaic.js +8 -0
  202. package/dist/mosaic.js.map +1 -0
  203. package/dist/prepare/detectGeometryColumn.d.ts +19 -0
  204. package/dist/prepare/detectGeometryColumn.d.ts.map +1 -0
  205. package/dist/prepare/detectGeometryColumn.js +126 -0
  206. package/dist/prepare/detectGeometryColumn.js.map +1 -0
  207. package/dist/prepare/geoarrow.d.ts +18 -0
  208. package/dist/prepare/geoarrow.d.ts.map +1 -0
  209. package/dist/prepare/geoarrow.js +114 -0
  210. package/dist/prepare/geoarrow.js.map +1 -0
  211. package/dist/prepare/geometryDecoder.d.ts +8 -0
  212. package/dist/prepare/geometryDecoder.d.ts.map +1 -0
  213. package/dist/prepare/geometryDecoder.js +2 -0
  214. package/dist/prepare/geometryDecoder.js.map +1 -0
  215. package/dist/prepare/prepareDeckDataset.d.ts +57 -0
  216. package/dist/prepare/prepareDeckDataset.d.ts.map +1 -0
  217. package/dist/prepare/prepareDeckDataset.js +112 -0
  218. package/dist/prepare/prepareDeckDataset.js.map +1 -0
  219. package/dist/prepare/toGeoJsonBinary.d.ts +9 -0
  220. package/dist/prepare/toGeoJsonBinary.d.ts.map +1 -0
  221. package/dist/prepare/toGeoJsonBinary.js +26 -0
  222. package/dist/prepare/toGeoJsonBinary.js.map +1 -0
  223. package/dist/prepare/types.d.ts +25 -0
  224. package/dist/prepare/types.d.ts.map +1 -0
  225. package/dist/prepare/types.js +2 -0
  226. package/dist/prepare/types.js.map +1 -0
  227. package/dist/prepare/wkbDecoder.d.ts +3 -0
  228. package/dist/prepare/wkbDecoder.d.ts.map +1 -0
  229. package/dist/prepare/wkbDecoder.js +419 -0
  230. package/dist/prepare/wkbDecoder.js.map +1 -0
  231. package/dist/prepare/wkbParser.d.ts +24 -0
  232. package/dist/prepare/wkbParser.d.ts.map +1 -0
  233. package/dist/prepare/wkbParser.js +139 -0
  234. package/dist/prepare/wkbParser.js.map +1 -0
  235. package/dist/types.d.ts +92 -0
  236. package/dist/types.d.ts.map +1 -0
  237. package/dist/types.js +11 -0
  238. package/dist/types.js.map +1 -0
  239. package/dist/useDeckMapDatasetSchema.d.ts +33 -0
  240. package/dist/useDeckMapDatasetSchema.d.ts.map +1 -0
  241. package/dist/useDeckMapDatasetSchema.js +138 -0
  242. package/dist/useDeckMapDatasetSchema.js.map +1 -0
  243. package/dist/useDeckMapDatasets.d.ts +17 -0
  244. package/dist/useDeckMapDatasets.d.ts.map +1 -0
  245. package/dist/useDeckMapDatasets.js +69 -0
  246. package/dist/useDeckMapDatasets.js.map +1 -0
  247. package/dist/useDeckMapFitToBounds.d.ts +31 -0
  248. package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
  249. package/dist/useDeckMapFitToBounds.js +58 -0
  250. package/dist/useDeckMapFitToBounds.js.map +1 -0
  251. package/package.json +98 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Returns the first dataset `source.tableName` found in a Deck map config.
3
+ */
4
+ export function getFirstDatasetSourceTableName(config) {
5
+ if (!config.datasets || typeof config.datasets !== 'object') {
6
+ return undefined;
7
+ }
8
+ return Object.values(config.datasets)
9
+ .map((dataset) => dataset.source)
10
+ .find((source) => source?.tableName)?.tableName;
11
+ }
12
+ /**
13
+ * Returns true when any dataset source is a literal `sqlQuery` without a
14
+ * structured `tableName` (so selected-table switching cannot apply).
15
+ */
16
+ export function hasSqlOnlyDatasetSource(config) {
17
+ if (!config.datasets || typeof config.datasets !== 'object') {
18
+ return false;
19
+ }
20
+ return Object.values(config.datasets).some((dataset) => {
21
+ const source = dataset.source;
22
+ return Boolean(source?.sqlQuery && !source.tableName);
23
+ });
24
+ }
25
+ //# sourceMappingURL=datasetSourceUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datasetSourceUtils.js","sourceRoot":"","sources":["../src/datasetSourceUtils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAAkC;IAElC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;SAClC,GAAG,CACF,CAAC,OAAO,EAAE,EAAE,CACT,OAAmC,CAAC,MAExB,CAChB;SACA,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAkC;IAElC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QACrD,MAAM,MAAM,GAAI,OAAmC,CAAC,MAEvC,CAAC;QACd,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Minimal Deck map config shape needed to inspect dataset sources.\n */\nexport type DeckMapDatasetSourceConfig = {\n datasets?: Record<string, unknown>;\n};\n\n/**\n * Returns the first dataset `source.tableName` found in a Deck map config.\n */\nexport function getFirstDatasetSourceTableName(\n config: DeckMapDatasetSourceConfig,\n): string | undefined {\n if (!config.datasets || typeof config.datasets !== 'object') {\n return undefined;\n }\n\n return Object.values(config.datasets)\n .map(\n (dataset) =>\n (dataset as Record<string, unknown>).source as\n | {tableName?: string}\n | undefined,\n )\n .find((source) => source?.tableName)?.tableName;\n}\n\n/**\n * Returns true when any dataset source is a literal `sqlQuery` without a\n * structured `tableName` (so selected-table switching cannot apply).\n */\nexport function hasSqlOnlyDatasetSource(\n config: DeckMapDatasetSourceConfig,\n): boolean {\n if (!config.datasets || typeof config.datasets !== 'object') {\n return false;\n }\n\n return Object.values(config.datasets).some((dataset) => {\n const source = (dataset as Record<string, unknown>).source as\n | {tableName?: string; sqlQuery?: string}\n | undefined;\n return Boolean(source?.sqlQuery && !source.tableName);\n });\n}\n"]}
@@ -0,0 +1,120 @@
1
+ import type { QueryHandle } from '@sqlrooms/duckdb';
2
+ import { type DeckDatasetInput, type PreparedDeckDatasetState } from '../types';
3
+ import type { PreparedDatasetCacheEntry, PreparedDatasetStoreOptions } from './types';
4
+ /**
5
+ * Internal store state for the prepared-dataset cache.
6
+ *
7
+ * `DeckJsonMap` never talks to this shape directly; `usePreparedDatasetStates`
8
+ * uses it as the backing state machine for preparation, reuse, and eviction.
9
+ */
10
+ type PreparedDatasetStoreState = {
11
+ /**
12
+ * Cache keys currently referenced by each hook consumer.
13
+ *
14
+ * This lets the store update consumer memberships incrementally when a map's
15
+ * dataset registry changes, instead of resetting all cache state.
16
+ */
17
+ consumerKeys: Record<string, string[]>;
18
+ /**
19
+ * Prepared entries keyed by resolved dataset identity.
20
+ *
21
+ * Keys are based on query/table identity plus geometry options, not dataset
22
+ * id, so the same prepared result can be reused across multiple maps or
23
+ * differently named datasets that point at the same underlying data.
24
+ */
25
+ entries: Record<string, PreparedDatasetCacheEntry>;
26
+ /**
27
+ * Ensure a cache entry exists for the given dataset key.
28
+ *
29
+ * If an entry already exists, this is a no-op other than touching its LRU
30
+ * metadata. Otherwise the store creates a `loading` entry, resolves the
31
+ * source table through DuckDB if needed, runs `prepareDeckDataset(...)`, and
32
+ * stores the resulting `ready` or `error` state.
33
+ */
34
+ ensureEntry: (options: {
35
+ cacheKey: string;
36
+ datasetId: string;
37
+ executeSql: (query: string, version?: number) => Promise<QueryHandle | null>;
38
+ input: DeckDatasetInput;
39
+ }) => void;
40
+ /**
41
+ * Remove all subscriptions for one hook consumer.
42
+ *
43
+ * This is called when a `DeckJsonMap` instance unmounts so the store can
44
+ * release the consumer's references and allow now-unreferenced entries to be
45
+ * evicted later.
46
+ */
47
+ removeConsumer: (consumerId: string) => void;
48
+ /**
49
+ * Reconcile the set of cache keys referenced by one hook consumer.
50
+ *
51
+ * This adds the consumer to newly needed entries, removes it from entries no
52
+ * longer needed, and preserves existing entries in place so unrelated dataset
53
+ * states do not get reset during prop changes.
54
+ */
55
+ syncConsumer: (consumerId: string, keys: string[]) => void;
56
+ /**
57
+ * Reconcile and ensure all prepared entries needed by one dataset registry.
58
+ *
59
+ * This is the store-level orchestration entrypoint used by
60
+ * `usePreparedDatasetStates`. It computes cache keys for the current dataset
61
+ * registry, syncs consumer memberships, and eagerly ensures any resolvable
62
+ * entries exist.
63
+ */
64
+ syncDatasetsForConsumer: (options: {
65
+ consumerId: string;
66
+ datasets: Record<string, DeckDatasetInput>;
67
+ executeSql: (query: string, version?: number) => Promise<QueryHandle | null>;
68
+ sqlSourceIdentity: object;
69
+ }) => void;
70
+ };
71
+ /**
72
+ * Create a feature-local cache store for prepared deck datasets.
73
+ *
74
+ * The store is intentionally scoped to deck's preparation layer. It reuses the
75
+ * expensive result of `prepareDeckDataset(...)` across consumers while leaving
76
+ * raw query/result caching to the upstream data provider:
77
+ *
78
+ * - Mosaic handles cached query results through its coordinator/query manager
79
+ * - DuckDB-backed SQL datasets still use the DuckDB slice execution path
80
+ *
81
+ * This keeps `@sqlrooms/deck` independent from either provider while still
82
+ * avoiding repeated geometry decoding and GeoArrow/GeoJSON shaping work.
83
+ */
84
+ export declare function createPreparedDatasetStore(options?: PreparedDatasetStoreOptions): import("zustand").StoreApi<PreparedDatasetStoreState>;
85
+ /**
86
+ * Resolve a shared prepared-store entry back into the dataset-state shape
87
+ * consumed by `DeckJsonMap`.
88
+ *
89
+ * Prepared entries are shared by cache key, while `datasetId` stays a
90
+ * view-level label used by layer binding and user-facing errors. When a shared
91
+ * prepared entry is reused for a different dataset id, this helper remaps the
92
+ * prepared payload so downstream callers still see the dataset id they asked
93
+ * for.
94
+ */
95
+ export declare function resolvePreparedDeckDatasetState(options: {
96
+ datasetId: string;
97
+ entry?: PreparedDatasetCacheEntry;
98
+ }): PreparedDeckDatasetState;
99
+ /**
100
+ * Resolve the full `datasetId -> state` map for a dataset registry.
101
+ *
102
+ * This mirrors the lookup logic used by `DeckJsonMap`: unresolved Arrow
103
+ * datasets remain `loading`, while resolvable datasets reuse shared prepared
104
+ * entries keyed by data identity rather than by dataset id.
105
+ */
106
+ export declare function resolvePreparedDeckDatasetStates(options: {
107
+ datasets: Record<string, DeckDatasetInput>;
108
+ entries: Record<string, PreparedDatasetCacheEntry>;
109
+ sqlSourceIdentity: object;
110
+ }): Record<string, PreparedDeckDatasetState>;
111
+ /**
112
+ * Module-global prepared dataset cache shared by all `DeckJsonMap` instances.
113
+ *
114
+ * The cache stores only deck-specific prepared payloads, not raw query
115
+ * results, and applies a small internal LRU policy so settled entries do not
116
+ * grow without bound.
117
+ */
118
+ export declare const preparedDatasetStore: import("zustand").StoreApi<PreparedDatasetStoreState>;
119
+ export {};
120
+ //# sourceMappingURL=PreparedDatasetStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreparedDatasetStore.d.ts","sourceRoot":"","sources":["../../src/datasets/PreparedDatasetStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC9B,MAAM,UAAU,CAAC;AAWlB,OAAO,KAAK,EACV,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAEjB;;;;;GAKG;AACH,KAAK,yBAAyB,GAAG;IAC/B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACnD;;;;;;;OAOG;IACH,WAAW,EAAE,CAAC,OAAO,EAAE;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;QACjC,KAAK,EAAE,gBAAgB,CAAC;KACzB,KAAK,IAAI,CAAC;IACX;;;;;;OAMG;IACH,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3D;;;;;;;OAOG;IACH,uBAAuB,EAAE,CAAC,OAAO,EAAE;QACjC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC3C,UAAU,EAAE,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;QACjC,iBAAiB,EAAE,MAAM,CAAC;KAC3B,KAAK,IAAI,CAAC;CACZ,CAAC;AAwBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,yDA8O1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,yBAAyB,CAAC;CACnC,GAAG,wBAAwB,CAqB3B;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE;IACxD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACnD,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAc3C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uDAA+B,CAAC"}
@@ -0,0 +1,268 @@
1
+ import { createStore } from 'zustand/vanilla';
2
+ import { prepareDeckDataset } from '../prepare/prepareDeckDataset';
3
+ import { isSqlDatasetInput, isTableDatasetInput, } from '../types';
4
+ import { DEFAULT_MAX_PREPARED_DATASET_ENTRIES, cloneEntryWithConsumers, evictLruEntries, nextAccessTimestamp, resolvePreparedDatasetCacheKey, touchEntry, } from './helpers';
5
+ import { resolveArrowTable } from './normalizeDatasets';
6
+ import { createDeckTableDatasetSql } from './tableDatasetSql';
7
+ function resolvePreparedDatasetDescriptors(options) {
8
+ const { datasets, sqlSourceIdentity } = options;
9
+ return Object.entries(datasets).map(([datasetId, input]) => ({
10
+ datasetId,
11
+ input,
12
+ cacheKey: resolvePreparedDatasetCacheKey({
13
+ input,
14
+ sqlSourceIdentity,
15
+ }),
16
+ }));
17
+ }
18
+ /**
19
+ * Create a feature-local cache store for prepared deck datasets.
20
+ *
21
+ * The store is intentionally scoped to deck's preparation layer. It reuses the
22
+ * expensive result of `prepareDeckDataset(...)` across consumers while leaving
23
+ * raw query/result caching to the upstream data provider:
24
+ *
25
+ * - Mosaic handles cached query results through its coordinator/query manager
26
+ * - DuckDB-backed SQL datasets still use the DuckDB slice execution path
27
+ *
28
+ * This keeps `@sqlrooms/deck` independent from either provider while still
29
+ * avoiding repeated geometry decoding and GeoArrow/GeoJSON shaping work.
30
+ */
31
+ export function createPreparedDatasetStore(options = {}) {
32
+ const { maxEntries = DEFAULT_MAX_PREPARED_DATASET_ENTRIES, prepareDataset = prepareDeckDataset, } = options;
33
+ return createStore((set, get) => ({
34
+ consumerKeys: {},
35
+ entries: {},
36
+ ensureEntry({ cacheKey, datasetId, executeSql, input }) {
37
+ const existing = get().entries[cacheKey];
38
+ if (existing) {
39
+ if (existing.status !== 'loading') {
40
+ set((state) => ({
41
+ ...state,
42
+ entries: {
43
+ ...state.entries,
44
+ [cacheKey]: touchEntry(existing),
45
+ },
46
+ }));
47
+ }
48
+ return;
49
+ }
50
+ const promise = Promise.resolve().then(async () => {
51
+ try {
52
+ let table = resolveArrowTable(input);
53
+ if (!table &&
54
+ (isSqlDatasetInput(input) || isTableDatasetInput(input))) {
55
+ const sql = isSqlDatasetInput(input)
56
+ ? input.sqlQuery
57
+ : createDeckTableDatasetSql(input);
58
+ const queryHandle = await executeSql(sql);
59
+ if (!queryHandle) {
60
+ throw new Error(`Query for dataset "${datasetId}" was cancelled.`);
61
+ }
62
+ table = await queryHandle;
63
+ }
64
+ if (!table) {
65
+ return;
66
+ }
67
+ const prepared = prepareDataset({
68
+ datasetId,
69
+ table,
70
+ geometryColumn: input.geometryColumn,
71
+ geometryEncodingHint: input.geometryEncodingHint,
72
+ });
73
+ set((state) => ({
74
+ ...state,
75
+ entries: evictLruEntries({
76
+ ...state.entries,
77
+ [cacheKey]: {
78
+ status: 'ready',
79
+ prepared,
80
+ consumers: state.entries[cacheKey]?.consumers ?? new Set(),
81
+ lastAccessedAt: nextAccessTimestamp(),
82
+ },
83
+ }, maxEntries),
84
+ }));
85
+ }
86
+ catch (error) {
87
+ set((state) => ({
88
+ ...state,
89
+ entries: evictLruEntries({
90
+ ...state.entries,
91
+ [cacheKey]: {
92
+ status: 'error',
93
+ error: error instanceof Error ? error : new Error(String(error)),
94
+ consumers: state.entries[cacheKey]?.consumers ?? new Set(),
95
+ lastAccessedAt: nextAccessTimestamp(),
96
+ },
97
+ }, maxEntries),
98
+ }));
99
+ }
100
+ });
101
+ set((state) => ({
102
+ ...state,
103
+ entries: {
104
+ ...state.entries,
105
+ [cacheKey]: {
106
+ status: 'loading',
107
+ promise,
108
+ consumers: state.entries[cacheKey]?.consumers ?? new Set(),
109
+ lastAccessedAt: nextAccessTimestamp(),
110
+ },
111
+ },
112
+ }));
113
+ },
114
+ syncConsumer(consumerId, keys) {
115
+ const previousKeys = new Set(get().consumerKeys[consumerId] ?? []);
116
+ const nextKeys = new Set(keys);
117
+ set((state) => {
118
+ let didChangeEntries = false;
119
+ let nextEntries = state.entries;
120
+ const updateEntry = (cacheKey, updater) => {
121
+ const currentEntry = nextEntries[cacheKey];
122
+ if (!currentEntry) {
123
+ return;
124
+ }
125
+ if (!didChangeEntries) {
126
+ nextEntries = { ...nextEntries };
127
+ didChangeEntries = true;
128
+ }
129
+ nextEntries[cacheKey] = updater(currentEntry);
130
+ };
131
+ for (const cacheKey of previousKeys) {
132
+ if (nextKeys.has(cacheKey)) {
133
+ continue;
134
+ }
135
+ updateEntry(cacheKey, (entry) => {
136
+ const consumers = new Set(entry.consumers);
137
+ consumers.delete(consumerId);
138
+ return cloneEntryWithConsumers(entry, consumers);
139
+ });
140
+ }
141
+ for (const cacheKey of nextKeys) {
142
+ updateEntry(cacheKey, (entry) => {
143
+ const consumers = new Set(entry.consumers);
144
+ consumers.add(consumerId);
145
+ return cloneEntryWithConsumers(entry, consumers);
146
+ });
147
+ }
148
+ return {
149
+ ...state,
150
+ consumerKeys: {
151
+ ...state.consumerKeys,
152
+ [consumerId]: [...nextKeys],
153
+ },
154
+ entries: didChangeEntries
155
+ ? evictLruEntries(nextEntries, maxEntries)
156
+ : state.entries,
157
+ };
158
+ });
159
+ },
160
+ removeConsumer(consumerId) {
161
+ const previousKeys = get().consumerKeys[consumerId];
162
+ if (!previousKeys) {
163
+ return;
164
+ }
165
+ set((state) => {
166
+ let didChangeEntries = false;
167
+ let nextEntries = state.entries;
168
+ for (const cacheKey of previousKeys) {
169
+ const entry = nextEntries[cacheKey];
170
+ if (!entry) {
171
+ continue;
172
+ }
173
+ const consumers = new Set(entry.consumers);
174
+ consumers.delete(consumerId);
175
+ if (!didChangeEntries) {
176
+ nextEntries = { ...nextEntries };
177
+ didChangeEntries = true;
178
+ }
179
+ nextEntries[cacheKey] = cloneEntryWithConsumers(entry, consumers);
180
+ }
181
+ const nextConsumerKeys = { ...state.consumerKeys };
182
+ delete nextConsumerKeys[consumerId];
183
+ return {
184
+ ...state,
185
+ consumerKeys: nextConsumerKeys,
186
+ entries: didChangeEntries
187
+ ? evictLruEntries(nextEntries, maxEntries)
188
+ : state.entries,
189
+ };
190
+ });
191
+ },
192
+ syncDatasetsForConsumer({ consumerId, datasets, executeSql, sqlSourceIdentity, }) {
193
+ const descriptors = resolvePreparedDatasetDescriptors({
194
+ datasets,
195
+ sqlSourceIdentity,
196
+ });
197
+ const cacheKeys = descriptors
198
+ .map((descriptor) => descriptor.cacheKey)
199
+ .filter((cacheKey) => Boolean(cacheKey));
200
+ for (const descriptor of descriptors) {
201
+ if (!descriptor.cacheKey) {
202
+ continue;
203
+ }
204
+ get().ensureEntry({
205
+ cacheKey: descriptor.cacheKey,
206
+ datasetId: descriptor.datasetId,
207
+ executeSql,
208
+ input: descriptor.input,
209
+ });
210
+ }
211
+ get().syncConsumer(consumerId, cacheKeys);
212
+ },
213
+ }));
214
+ }
215
+ /**
216
+ * Resolve a shared prepared-store entry back into the dataset-state shape
217
+ * consumed by `DeckJsonMap`.
218
+ *
219
+ * Prepared entries are shared by cache key, while `datasetId` stays a
220
+ * view-level label used by layer binding and user-facing errors. When a shared
221
+ * prepared entry is reused for a different dataset id, this helper remaps the
222
+ * prepared payload so downstream callers still see the dataset id they asked
223
+ * for.
224
+ */
225
+ export function resolvePreparedDeckDatasetState(options) {
226
+ const { datasetId, entry } = options;
227
+ if (!entry || entry.status === 'loading') {
228
+ return { status: 'loading' };
229
+ }
230
+ if (entry.status === 'error') {
231
+ return { status: 'error', error: entry.error };
232
+ }
233
+ return {
234
+ status: 'ready',
235
+ prepared: entry.prepared.datasetId === datasetId
236
+ ? entry.prepared
237
+ : {
238
+ ...entry.prepared,
239
+ datasetId,
240
+ },
241
+ };
242
+ }
243
+ /**
244
+ * Resolve the full `datasetId -> state` map for a dataset registry.
245
+ *
246
+ * This mirrors the lookup logic used by `DeckJsonMap`: unresolved Arrow
247
+ * datasets remain `loading`, while resolvable datasets reuse shared prepared
248
+ * entries keyed by data identity rather than by dataset id.
249
+ */
250
+ export function resolvePreparedDeckDatasetStates(options) {
251
+ const { datasets, entries, sqlSourceIdentity } = options;
252
+ return Object.fromEntries(resolvePreparedDatasetDescriptors({ datasets, sqlSourceIdentity }).map(({ datasetId, cacheKey }) => [
253
+ datasetId,
254
+ resolvePreparedDeckDatasetState({
255
+ datasetId,
256
+ entry: cacheKey ? entries[cacheKey] : undefined,
257
+ }),
258
+ ]));
259
+ }
260
+ /**
261
+ * Module-global prepared dataset cache shared by all `DeckJsonMap` instances.
262
+ *
263
+ * The cache stores only deck-specific prepared payloads, not raw query
264
+ * results, and applies a small internal LRU policy so settled entries do not
265
+ * grow without bound.
266
+ */
267
+ export const preparedDatasetStore = createPreparedDatasetStore();
268
+ //# sourceMappingURL=PreparedDatasetStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PreparedDatasetStore.js","sourceRoot":"","sources":["../../src/datasets/PreparedDatasetStore.ts"],"names":[],"mappings":"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","sourcesContent":["import type {QueryHandle} from '@sqlrooms/duckdb';\nimport {createStore} from 'zustand/vanilla';\nimport {prepareDeckDataset} from '../prepare/prepareDeckDataset';\nimport {\n isSqlDatasetInput,\n isTableDatasetInput,\n type DeckDatasetInput,\n type PreparedDeckDatasetState,\n} from '../types';\nimport {\n DEFAULT_MAX_PREPARED_DATASET_ENTRIES,\n cloneEntryWithConsumers,\n evictLruEntries,\n nextAccessTimestamp,\n resolvePreparedDatasetCacheKey,\n touchEntry,\n} from './helpers';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport {createDeckTableDatasetSql} from './tableDatasetSql';\nimport type {\n PreparedDatasetCacheEntry,\n PreparedDatasetStoreOptions,\n} from './types';\n\n/**\n * Internal store state for the prepared-dataset cache.\n *\n * `DeckJsonMap` never talks to this shape directly; `usePreparedDatasetStates`\n * uses it as the backing state machine for preparation, reuse, and eviction.\n */\ntype PreparedDatasetStoreState = {\n /**\n * Cache keys currently referenced by each hook consumer.\n *\n * This lets the store update consumer memberships incrementally when a map's\n * dataset registry changes, instead of resetting all cache state.\n */\n consumerKeys: Record<string, string[]>;\n /**\n * Prepared entries keyed by resolved dataset identity.\n *\n * Keys are based on query/table identity plus geometry options, not dataset\n * id, so the same prepared result can be reused across multiple maps or\n * differently named datasets that point at the same underlying data.\n */\n entries: Record<string, PreparedDatasetCacheEntry>;\n /**\n * Ensure a cache entry exists for the given dataset key.\n *\n * If an entry already exists, this is a no-op other than touching its LRU\n * metadata. Otherwise the store creates a `loading` entry, resolves the\n * source table through DuckDB if needed, runs `prepareDeckDataset(...)`, and\n * stores the resulting `ready` or `error` state.\n */\n ensureEntry: (options: {\n cacheKey: string;\n datasetId: string;\n executeSql: (\n query: string,\n version?: number,\n ) => Promise<QueryHandle | null>;\n input: DeckDatasetInput;\n }) => void;\n /**\n * Remove all subscriptions for one hook consumer.\n *\n * This is called when a `DeckJsonMap` instance unmounts so the store can\n * release the consumer's references and allow now-unreferenced entries to be\n * evicted later.\n */\n removeConsumer: (consumerId: string) => void;\n /**\n * Reconcile the set of cache keys referenced by one hook consumer.\n *\n * This adds the consumer to newly needed entries, removes it from entries no\n * longer needed, and preserves existing entries in place so unrelated dataset\n * states do not get reset during prop changes.\n */\n syncConsumer: (consumerId: string, keys: string[]) => void;\n /**\n * Reconcile and ensure all prepared entries needed by one dataset registry.\n *\n * This is the store-level orchestration entrypoint used by\n * `usePreparedDatasetStates`. It computes cache keys for the current dataset\n * registry, syncs consumer memberships, and eagerly ensures any resolvable\n * entries exist.\n */\n syncDatasetsForConsumer: (options: {\n consumerId: string;\n datasets: Record<string, DeckDatasetInput>;\n executeSql: (\n query: string,\n version?: number,\n ) => Promise<QueryHandle | null>;\n sqlSourceIdentity: object;\n }) => void;\n};\n\ntype PreparedDatasetDescriptor = {\n datasetId: string;\n input: DeckDatasetInput;\n cacheKey: string | undefined;\n};\n\nfunction resolvePreparedDatasetDescriptors(options: {\n datasets: Record<string, DeckDatasetInput>;\n sqlSourceIdentity: object;\n}): PreparedDatasetDescriptor[] {\n const {datasets, sqlSourceIdentity} = options;\n\n return Object.entries(datasets).map(([datasetId, input]) => ({\n datasetId,\n input,\n cacheKey: resolvePreparedDatasetCacheKey({\n input,\n sqlSourceIdentity,\n }),\n }));\n}\n\n/**\n * Create a feature-local cache store for prepared deck datasets.\n *\n * The store is intentionally scoped to deck's preparation layer. It reuses the\n * expensive result of `prepareDeckDataset(...)` across consumers while leaving\n * raw query/result caching to the upstream data provider:\n *\n * - Mosaic handles cached query results through its coordinator/query manager\n * - DuckDB-backed SQL datasets still use the DuckDB slice execution path\n *\n * This keeps `@sqlrooms/deck` independent from either provider while still\n * avoiding repeated geometry decoding and GeoArrow/GeoJSON shaping work.\n */\nexport function createPreparedDatasetStore(\n options: PreparedDatasetStoreOptions = {},\n) {\n const {\n maxEntries = DEFAULT_MAX_PREPARED_DATASET_ENTRIES,\n prepareDataset = prepareDeckDataset,\n } = options;\n\n return createStore<PreparedDatasetStoreState>((set, get) => ({\n consumerKeys: {},\n entries: {},\n\n ensureEntry({cacheKey, datasetId, executeSql, input}) {\n const existing = get().entries[cacheKey];\n if (existing) {\n if (existing.status !== 'loading') {\n set((state) => ({\n ...state,\n entries: {\n ...state.entries,\n [cacheKey]: touchEntry(existing),\n },\n }));\n }\n return;\n }\n\n const promise = Promise.resolve().then(async () => {\n try {\n let table = resolveArrowTable(input);\n if (\n !table &&\n (isSqlDatasetInput(input) || isTableDatasetInput(input))\n ) {\n const sql = isSqlDatasetInput(input)\n ? input.sqlQuery\n : createDeckTableDatasetSql(input);\n const queryHandle = await executeSql(sql);\n if (!queryHandle) {\n throw new Error(\n `Query for dataset \"${datasetId}\" was cancelled.`,\n );\n }\n\n table = await queryHandle;\n }\n\n if (!table) {\n return;\n }\n\n const prepared = prepareDataset({\n datasetId,\n table,\n geometryColumn: input.geometryColumn,\n geometryEncodingHint: input.geometryEncodingHint,\n });\n\n set((state) => ({\n ...state,\n entries: evictLruEntries(\n {\n ...state.entries,\n [cacheKey]: {\n status: 'ready',\n prepared,\n consumers:\n state.entries[cacheKey]?.consumers ?? new Set<string>(),\n lastAccessedAt: nextAccessTimestamp(),\n },\n },\n maxEntries,\n ),\n }));\n } catch (error) {\n set((state) => ({\n ...state,\n entries: evictLruEntries(\n {\n ...state.entries,\n [cacheKey]: {\n status: 'error',\n error:\n error instanceof Error ? error : new Error(String(error)),\n consumers:\n state.entries[cacheKey]?.consumers ?? new Set<string>(),\n lastAccessedAt: nextAccessTimestamp(),\n },\n },\n maxEntries,\n ),\n }));\n }\n });\n\n set((state) => ({\n ...state,\n entries: {\n ...state.entries,\n [cacheKey]: {\n status: 'loading',\n promise,\n consumers: state.entries[cacheKey]?.consumers ?? new Set<string>(),\n lastAccessedAt: nextAccessTimestamp(),\n },\n },\n }));\n },\n\n syncConsumer(consumerId, keys) {\n const previousKeys = new Set(get().consumerKeys[consumerId] ?? []);\n const nextKeys = new Set(keys);\n\n set((state) => {\n let didChangeEntries = false;\n let nextEntries = state.entries;\n\n const updateEntry = (\n cacheKey: string,\n updater: (\n entry: PreparedDatasetCacheEntry,\n ) => PreparedDatasetCacheEntry,\n ) => {\n const currentEntry = nextEntries[cacheKey];\n if (!currentEntry) {\n return;\n }\n\n if (!didChangeEntries) {\n nextEntries = {...nextEntries};\n didChangeEntries = true;\n }\n\n nextEntries[cacheKey] = updater(currentEntry);\n };\n\n for (const cacheKey of previousKeys) {\n if (nextKeys.has(cacheKey)) {\n continue;\n }\n\n updateEntry(cacheKey, (entry) => {\n const consumers = new Set(entry.consumers);\n consumers.delete(consumerId);\n return cloneEntryWithConsumers(entry, consumers);\n });\n }\n\n for (const cacheKey of nextKeys) {\n updateEntry(cacheKey, (entry) => {\n const consumers = new Set(entry.consumers);\n consumers.add(consumerId);\n return cloneEntryWithConsumers(entry, consumers);\n });\n }\n\n return {\n ...state,\n consumerKeys: {\n ...state.consumerKeys,\n [consumerId]: [...nextKeys],\n },\n entries: didChangeEntries\n ? evictLruEntries(nextEntries, maxEntries)\n : state.entries,\n };\n });\n },\n\n removeConsumer(consumerId) {\n const previousKeys = get().consumerKeys[consumerId];\n if (!previousKeys) {\n return;\n }\n\n set((state) => {\n let didChangeEntries = false;\n let nextEntries = state.entries;\n\n for (const cacheKey of previousKeys) {\n const entry = nextEntries[cacheKey];\n if (!entry) {\n continue;\n }\n\n const consumers = new Set(entry.consumers);\n consumers.delete(consumerId);\n\n if (!didChangeEntries) {\n nextEntries = {...nextEntries};\n didChangeEntries = true;\n }\n\n nextEntries[cacheKey] = cloneEntryWithConsumers(entry, consumers);\n }\n\n const nextConsumerKeys = {...state.consumerKeys};\n delete nextConsumerKeys[consumerId];\n\n return {\n ...state,\n consumerKeys: nextConsumerKeys,\n entries: didChangeEntries\n ? evictLruEntries(nextEntries, maxEntries)\n : state.entries,\n };\n });\n },\n\n syncDatasetsForConsumer({\n consumerId,\n datasets,\n executeSql,\n sqlSourceIdentity,\n }) {\n const descriptors = resolvePreparedDatasetDescriptors({\n datasets,\n sqlSourceIdentity,\n });\n const cacheKeys = descriptors\n .map((descriptor) => descriptor.cacheKey)\n .filter((cacheKey): cacheKey is string => Boolean(cacheKey));\n\n for (const descriptor of descriptors) {\n if (!descriptor.cacheKey) {\n continue;\n }\n\n get().ensureEntry({\n cacheKey: descriptor.cacheKey,\n datasetId: descriptor.datasetId,\n executeSql,\n input: descriptor.input,\n });\n }\n\n get().syncConsumer(consumerId, cacheKeys);\n },\n }));\n}\n\n/**\n * Resolve a shared prepared-store entry back into the dataset-state shape\n * consumed by `DeckJsonMap`.\n *\n * Prepared entries are shared by cache key, while `datasetId` stays a\n * view-level label used by layer binding and user-facing errors. When a shared\n * prepared entry is reused for a different dataset id, this helper remaps the\n * prepared payload so downstream callers still see the dataset id they asked\n * for.\n */\nexport function resolvePreparedDeckDatasetState(options: {\n datasetId: string;\n entry?: PreparedDatasetCacheEntry;\n}): PreparedDeckDatasetState {\n const {datasetId, entry} = options;\n\n if (!entry || entry.status === 'loading') {\n return {status: 'loading'};\n }\n\n if (entry.status === 'error') {\n return {status: 'error', error: entry.error};\n }\n\n return {\n status: 'ready',\n prepared:\n entry.prepared.datasetId === datasetId\n ? entry.prepared\n : {\n ...entry.prepared,\n datasetId,\n },\n };\n}\n\n/**\n * Resolve the full `datasetId -> state` map for a dataset registry.\n *\n * This mirrors the lookup logic used by `DeckJsonMap`: unresolved Arrow\n * datasets remain `loading`, while resolvable datasets reuse shared prepared\n * entries keyed by data identity rather than by dataset id.\n */\nexport function resolvePreparedDeckDatasetStates(options: {\n datasets: Record<string, DeckDatasetInput>;\n entries: Record<string, PreparedDatasetCacheEntry>;\n sqlSourceIdentity: object;\n}): Record<string, PreparedDeckDatasetState> {\n const {datasets, entries, sqlSourceIdentity} = options;\n\n return Object.fromEntries(\n resolvePreparedDatasetDescriptors({datasets, sqlSourceIdentity}).map(\n ({datasetId, cacheKey}) => [\n datasetId,\n resolvePreparedDeckDatasetState({\n datasetId,\n entry: cacheKey ? entries[cacheKey] : undefined,\n }),\n ],\n ),\n );\n}\n\n/**\n * Module-global prepared dataset cache shared by all `DeckJsonMap` instances.\n *\n * The cache stores only deck-specific prepared payloads, not raw query\n * results, and applies a small internal LRU policy so settled entries do not\n * grow without bound.\n */\nexport const preparedDatasetStore = createPreparedDatasetStore();\n"]}
@@ -0,0 +1,57 @@
1
+ import type * as arrow from 'apache-arrow';
2
+ import { type DeckDatasetInput } from '../types';
3
+ import type { PreparedDatasetCacheEntry } from './types';
4
+ export declare const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;
5
+ /** Return a monotonic access timestamp used by the prepared-dataset LRU. */
6
+ export declare function nextAccessTimestamp(): number;
7
+ /**
8
+ * Assign a stable cache identity to an Arrow table object.
9
+ *
10
+ * Table identities are stored in a `WeakMap` so this cache does not extend the
11
+ * lifetime of tables once they are no longer referenced elsewhere.
12
+ */
13
+ export declare function getTableIdentity(table: arrow.Table): string;
14
+ /**
15
+ * Assign a stable cache identity to the current SQL source object.
16
+ *
17
+ * For SQL datasets we include the upstream DuckDB connector identity in the
18
+ * cache key so two rooms using the same SQL text do not accidentally share
19
+ * prepared results across different database instances.
20
+ */
21
+ export declare function getSqlSourceIdentity(sqlSourceIdentity: object): string;
22
+ export declare function buildGeometryKey(input: DeckDatasetInput): string;
23
+ /**
24
+ * Build the canonical cache key for one dataset input.
25
+ *
26
+ * The key intentionally ignores the user-facing dataset id and instead uses
27
+ * the underlying data identity:
28
+ *
29
+ * - SQL/table datasets: DuckDB connector identity + compiled SQL + geometry options
30
+ * - Arrow datasets: table object identity + geometry options
31
+ *
32
+ * Unresolved Arrow inputs (`arrowTable: undefined`) return `undefined`, which
33
+ * signals that the dataset should remain in `loading` until a table exists.
34
+ */
35
+ export declare function resolvePreparedDatasetCacheKey(options: {
36
+ input: DeckDatasetInput;
37
+ sqlSourceIdentity?: object;
38
+ }): string | undefined;
39
+ /**
40
+ * Clone a cache entry while replacing its consumer set and refreshing the
41
+ * access timestamp.
42
+ *
43
+ * This keeps the discriminated union shape intact while centralizing the
44
+ * bookkeeping needed by consumer reconciliation and LRU tracking.
45
+ */
46
+ export declare function cloneEntryWithConsumers(entry: PreparedDatasetCacheEntry, consumers: Set<string>): PreparedDatasetCacheEntry;
47
+ /** Mark an entry as recently used without changing its lifecycle payload. */
48
+ export declare function touchEntry(entry: PreparedDatasetCacheEntry): PreparedDatasetCacheEntry;
49
+ /**
50
+ * Evict least-recently-used settled entries when the cache exceeds capacity.
51
+ *
52
+ * Only `ready` and `error` entries participate in eviction. `loading` entries
53
+ * are preserved so in-flight work is not discarded, and referenced entries are
54
+ * preserved so active maps never lose their prepared data mid-render.
55
+ */
56
+ export declare function evictLruEntries(entries: Record<string, PreparedDatasetCacheEntry>, maxEntries: number): Record<string, PreparedDatasetCacheEntry>;
57
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/datasets/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,SAAS,CAAC;AAEvD,eAAO,MAAM,oCAAoC,KAAK,CAAC;AASvD,4EAA4E;AAC5E,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAU3D;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAUtE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,KAAK,EAAE,gBAAgB,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,GAAG,SAAS,CAoCrB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,yBAAyB,EAChC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,yBAAyB,CA2B3B;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CACxB,KAAK,EAAE,yBAAyB,GAC/B,yBAAyB,CAE3B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,EAClD,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CA8B3C"}