@sqlrooms/deck 0.29.0-rc.11 → 0.29.0-rc.13
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.
- package/README.md +193 -35
- package/dist/BlockMapSettings.d.ts.map +1 -1
- package/dist/BlockMapSettings.js +4 -16
- package/dist/BlockMapSettings.js.map +1 -1
- package/dist/DashboardMapSettings.d.ts.map +1 -1
- package/dist/DashboardMapSettings.js +7 -10
- package/dist/DashboardMapSettings.js.map +1 -1
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +75 -23
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/DeckJsonMapSpec.d.ts +41 -0
- package/dist/DeckJsonMapSpec.d.ts.map +1 -1
- package/dist/DeckJsonMapSpec.js +2 -0
- package/dist/DeckJsonMapSpec.js.map +1 -1
- package/dist/DeckMapBasemapSelect.d.ts +9 -0
- package/dist/DeckMapBasemapSelect.d.ts.map +1 -0
- package/dist/DeckMapBasemapSelect.js +20 -0
- package/dist/DeckMapBasemapSelect.js.map +1 -0
- package/dist/DeckMapDefaultStylesProvider.d.ts +13 -19
- package/dist/DeckMapDefaultStylesProvider.d.ts.map +1 -1
- package/dist/DeckMapDefaultStylesProvider.js +11 -18
- package/dist/DeckMapDefaultStylesProvider.js.map +1 -1
- package/dist/DeckMapSurface.d.ts +1 -1
- package/dist/DeckMapSurface.js +1 -1
- package/dist/DeckMapSurface.js.map +1 -1
- package/dist/DeckMapsSlice.d.ts +5 -0
- package/dist/DeckMapsSlice.d.ts.map +1 -1
- package/dist/DeckMapsSlice.js +6 -3
- package/dist/DeckMapsSlice.js.map +1 -1
- package/dist/MapSettings.d.ts +14 -0
- package/dist/MapSettings.d.ts.map +1 -1
- package/dist/MapSettings.js +548 -192
- package/dist/MapSettings.js.map +1 -1
- package/dist/MapSettingsControls.d.ts +8 -1
- package/dist/MapSettingsControls.d.ts.map +1 -1
- package/dist/MapSettingsControls.js +24 -2
- package/dist/MapSettingsControls.js.map +1 -1
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +20 -12
- package/dist/ai.js.map +1 -1
- package/dist/aiNormalize.d.ts.map +1 -1
- package/dist/aiNormalize.js +2 -1
- package/dist/aiNormalize.js.map +1 -1
- package/dist/basemap.d.ts +23 -0
- package/dist/basemap.d.ts.map +1 -0
- package/dist/basemap.js +23 -0
- package/dist/basemap.js.map +1 -0
- package/dist/block.d.ts +1 -1
- package/dist/block.d.ts.map +1 -1
- package/dist/block.js +13 -9
- package/dist/block.js.map +1 -1
- package/dist/createOrUpdateDeckMapResource.d.ts +6 -2
- package/dist/createOrUpdateDeckMapResource.d.ts.map +1 -1
- package/dist/createOrUpdateDeckMapResource.js +57 -4
- package/dist/createOrUpdateDeckMapResource.js.map +1 -1
- package/dist/datasets/PreparedDatasetStore.d.ts +3 -4
- package/dist/datasets/PreparedDatasetStore.d.ts.map +1 -1
- package/dist/datasets/PreparedDatasetStore.js +4 -8
- package/dist/datasets/PreparedDatasetStore.js.map +1 -1
- package/dist/datasets/helpers.d.ts +39 -2
- package/dist/datasets/helpers.d.ts.map +1 -1
- package/dist/datasets/helpers.js +86 -3
- package/dist/datasets/helpers.js.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.d.ts.map +1 -1
- package/dist/datasets/usePreparedDatasetStates.js +12 -8
- package/dist/datasets/usePreparedDatasetStates.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/json/colorScaleFunction.d.ts +12 -4
- package/dist/json/colorScaleFunction.d.ts.map +1 -1
- package/dist/json/colorScaleFunction.js.map +1 -1
- package/dist/json/compileColorScale.d.ts +3 -2
- package/dist/json/compileColorScale.d.ts.map +1 -1
- package/dist/json/compileColorScale.js +16 -1
- package/dist/json/compileColorScale.js.map +1 -1
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
- package/dist/json/createDeckJsonConfiguration.js +235 -175
- package/dist/json/createDeckJsonConfiguration.js.map +1 -1
- package/dist/json/defaultClasses.d.ts.map +1 -1
- package/dist/json/defaultClasses.js +3 -3
- package/dist/json/defaultClasses.js.map +1 -1
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
- package/dist/json/extractColorScaleLegends.js +41 -26
- package/dist/json/extractColorScaleLegends.js.map +1 -1
- package/dist/json/heatmapDefaults.d.ts +17 -7
- package/dist/json/heatmapDefaults.d.ts.map +1 -1
- package/dist/json/heatmapDefaults.js +54 -12
- package/dist/json/heatmapDefaults.js.map +1 -1
- package/dist/json/layers/DeckHeatmapLayer.d.ts +32 -0
- package/dist/json/layers/DeckHeatmapLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckHeatmapLayer.js +69 -0
- package/dist/json/layers/DeckHeatmapLayer.js.map +1 -0
- package/dist/json/layers/index.d.ts +1 -0
- package/dist/json/layers/index.d.ts.map +1 -1
- package/dist/json/layers/index.js +1 -0
- package/dist/json/layers/index.js.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.js +13 -5
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
- package/dist/json/scaleFunction.d.ts +5 -8
- package/dist/json/scaleFunction.d.ts.map +1 -1
- package/dist/json/scaleFunction.js +30 -5
- package/dist/json/scaleFunction.js.map +1 -1
- package/dist/mapAiConfig.d.ts +6 -0
- package/dist/mapAiConfig.d.ts.map +1 -1
- package/dist/mapAiConfig.js +7 -0
- package/dist/mapAiConfig.js.map +1 -1
- package/dist/mapAiSharedInstructions.d.ts +1 -1
- package/dist/mapAiSharedInstructions.d.ts.map +1 -1
- package/dist/mapAiSharedInstructions.js +4 -3
- package/dist/mapAiSharedInstructions.js.map +1 -1
- package/dist/mapConfig.d.ts +6 -1
- package/dist/mapConfig.d.ts.map +1 -1
- package/dist/mapConfig.js +28 -3
- package/dist/mapConfig.js.map +1 -1
- package/dist/mapConfigUtils.d.ts +22 -0
- package/dist/mapConfigUtils.d.ts.map +1 -1
- package/dist/mapConfigUtils.js +152 -5
- package/dist/mapConfigUtils.js.map +1 -1
- package/dist/mapLayerConfigUtils.d.ts +55 -0
- package/dist/mapLayerConfigUtils.d.ts.map +1 -1
- package/dist/mapLayerConfigUtils.js +222 -11
- package/dist/mapLayerConfigUtils.js.map +1 -1
- package/dist/mapResourceAuthoring.d.ts +1 -1
- package/dist/mapResourceAuthoring.d.ts.map +1 -1
- package/dist/mapResourceAuthoring.js +14 -7
- package/dist/mapResourceAuthoring.js.map +1 -1
- package/dist/mapStyles.d.ts +16 -0
- package/dist/mapStyles.d.ts.map +1 -0
- package/dist/mapStyles.js +32 -0
- package/dist/mapStyles.js.map +1 -0
- package/dist/prepare/prepareDeckDataset.d.ts.map +1 -1
- package/dist/prepare/prepareDeckDataset.js +1 -0
- package/dist/prepare/prepareDeckDataset.js.map +1 -1
- package/dist/prepare/types.d.ts +3 -0
- package/dist/prepare/types.d.ts.map +1 -1
- package/dist/prepare/types.js.map +1 -1
- package/dist/prepare/wkbDecoder.d.ts.map +1 -1
- package/dist/prepare/wkbDecoder.js +62 -16
- package/dist/prepare/wkbDecoder.js.map +1 -1
- package/dist/prepare/wkbParser.d.ts +2 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -1
- package/dist/prepare/wkbParser.js +1 -0
- package/dist/prepare/wkbParser.js.map +1 -1
- package/dist/protomapsStyles.d.ts +18 -0
- package/dist/protomapsStyles.d.ts.map +1 -0
- package/dist/protomapsStyles.js +38 -0
- package/dist/protomapsStyles.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +11 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createOrUpdateDeckMapResource.js","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,2BAA2B,EAAC,MAAM,wBAAwB,CAAC;AA2EnE,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,IAAuC,EACvC,MAA2C;IAE3C,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,gBAAgB,CAAC;IAC/D,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK;QAChC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC;QACzD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,eAAe,GAAG,MAAM,CAAC,uBAAuB,IAAI,OAAO,CAAC;IAClE,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,aAAa,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,cAAc,MAAM,CAAC,KAAK,qBAAqB,MAAM,CAAC,eAAe,EAAE,CACxF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7E,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAE3E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,cAAc,GAClB,MAAM,CAAC,SAAS,IAAI,8BAA8B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa;QACvC,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,iBAAiB,EAAE,WAAW,EAAE,MAAM;YACtC,SAAS,EAAE,cAAc;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC;QACJ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IAClB,2BAA2B,CAAC,cAAc,CAAC,CAAC;IAC5C,MAAM,SAAS,GACb,cAAc,IAAI,8BAA8B,CAAC,cAAc,CAAC,CAAC;IACnE,IACE,CAAC,MAAM,CAAC,gCAAgC,IAAI,IAAI,CAAC;QACjD,aAAa;QACb,CAAC,SAAS;QACV,uBAAuB,CAAC,MAAM,CAAC,MAAM,CAAC,EACtC,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yCAAyC,aAAa,2CAA2C,CAClG,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,IAAI,SAAS,IAAI,CAAC,KAAK;QACrB,MAAM,IAAI,KAAK,CAAC,UAAU,SAAS,kBAAkB,CAAC,CAAC;IAEzD,MAAM,OAAO,GACX,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;QACtB,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE;QACpB,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE;QAC9B,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE;QAC1B,KAAK,CAAC;IACR,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC;IAC9C,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC;IAC/B,MAAM,KAAK,GACT,aAAa;QACb,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC;YACzB,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,KAAK;YACL,KAAK;YACL,OAAO;YACP,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC,CAAC;IACN,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACnC,MAAM,IAAI,CAAC,QAAQ,CAAC;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK;QACL,MAAM,EAAE,cAAc;QACtB,aAAa,EAAE,KAAK,EAAE,aAAa;KACpC,CAAC,CAAC;IACH,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI,CAAC,mBAAmB,CAAC;YAC7B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO;YACP,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,aAAa,EAAE,KAAK,EAAE,aAAa;QACnC,OAAO;QACP,OAAO,EAAE,OAAO;YACd,CAAC,CAAC,SAAS,aAAa,eAAe,KAAK,IAAI;YAChD,CAAC,CAAC,WAAW,aAAa,eAAe,KAAK,IAAI;KACrD,CAAC;AACJ,CAAC","sourcesContent":["import type {DeckMapResource} from './DeckMapsSlice';\nimport type {DeckMapConfig} from './mapConfig';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\n\n/**\n * Host callbacks used to coordinate a durable Deck map resource with its block\n * document container, table registry, and optional config preparation.\n */\nexport type CreateOrUpdateDeckMapResourceHost = {\n ensureBlockDocument: (blockDocumentId: string) => void;\n findMapBlock: (\n blockDocumentId: string,\n mapId: string,\n ) => {blockId: string; mapId: string; caption?: string} | undefined;\n findMap: (mapId: string) => DeckMapResource | undefined;\n createMapBlock: (options: {\n blockDocumentId: string;\n mapId: string;\n title: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => Promise<{blockId: string; mapId: string}>;\n updateBlockMetadata: (options: {\n blockDocumentId: string;\n blockId: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => void | Promise<void>;\n ensureMap: (mapId: string, title: string) => void;\n writeMap: (options: {\n mapId: string;\n title: string;\n config: DeckMapConfig;\n selectedTable?: string;\n }) => void | Promise<void>;\n findTable: (tableName: string) => {tableIdentity: string} | undefined;\n prepareConfig?: (options: {\n config: DeckMapConfig;\n existingMapConfig?: DeckMapConfig;\n tableName?: string;\n replaceLayers?: boolean;\n replaceDatasets?: boolean;\n }) => DeckMapConfig | Promise<DeckMapConfig>;\n};\n\n/** Input for creating or updating a Deck map resource and its owning block. */\nexport type CreateOrUpdateDeckMapResourceParams = {\n blockDocumentId: string;\n config: DeckMapConfig;\n mapId?: string;\n tableName?: string;\n title?: string;\n caption?: string;\n intent?: string;\n height?: number;\n /** Treat `config.spec.layers` as the complete replacement layer list. */\n replaceLayers?: boolean;\n /** Treat `config.datasets` as the complete replacement dataset registry. */\n replaceDatasets?: boolean;\n requireTableNameForSqlOnlyUpdate?: boolean;\n artifactLabel?: string;\n createMapId?: () => string;\n missingMapBlockBehavior?: 'throw' | 'create';\n};\n\n/** Result identities and resolved table selection from a map resource write. */\nexport type CreateOrUpdateDeckMapResourceResult = {\n blockDocumentId: string;\n blockId: string;\n mapId: string;\n selectedTable?: string;\n message: string;\n created: boolean;\n};\n\n/** Resource-native worksheet map orchestration with metadata-after-map-write ordering. */\nexport async function createOrUpdateDeckMapResource(\n host: CreateOrUpdateDeckMapResourceHost,\n params: CreateOrUpdateDeckMapResourceParams,\n): Promise<CreateOrUpdateDeckMapResourceResult> {\n const artifactLabel = params.artifactLabel ?? 'block document';\n host.ensureBlockDocument(params.blockDocumentId);\n const existingBlock = params.mapId\n ? host.findMapBlock(params.blockDocumentId, params.mapId)\n : undefined;\n const missingBehavior = params.missingMapBlockBehavior ?? 'throw';\n if (params.mapId && !existingBlock && missingBehavior === 'throw') {\n throw new Error(\n `${artifactLabel} map block ${params.mapId} was not found in ${params.blockDocumentId}`,\n );\n }\n const mapId = existingBlock?.mapId ?? params.mapId ?? params.createMapId?.();\n if (!mapId) throw new Error('mapId is required when creating a map block');\n\n const existingMap = host.findMap(mapId);\n const requestedTable =\n params.tableName ?? getFirstDatasetSourceTableName(params.config);\n const preparedConfig = host.prepareConfig\n ? await host.prepareConfig({\n config: params.config,\n existingMapConfig: existingMap?.config,\n tableName: requestedTable,\n replaceLayers: params.replaceLayers,\n replaceDatasets: params.replaceDatasets,\n })\n : params.config;\n assertDeckMapResourceConfig(preparedConfig);\n const tableName =\n requestedTable ?? getFirstDatasetSourceTableName(preparedConfig);\n if (\n (params.requireTableNameForSqlOnlyUpdate ?? true) &&\n existingBlock &&\n !tableName &&\n hasSqlOnlyDatasetSource(params.config)\n ) {\n throw new Error(\n `tableName is required when updating a ${artifactLabel} map block with SQL-only dataset sources.`,\n );\n }\n const table = tableName ? host.findTable(tableName) : undefined;\n if (tableName && !table)\n throw new Error(`Table \"${tableName}\" was not found.`);\n\n const caption =\n params.caption?.trim() ||\n params.title?.trim() ||\n existingBlock?.caption?.trim() ||\n existingMap?.title?.trim() ||\n 'Map';\n const title = params.title?.trim() || caption;\n const created = !existingBlock;\n const block =\n existingBlock ??\n (await host.createMapBlock({\n blockDocumentId: params.blockDocumentId,\n mapId,\n title,\n caption,\n intent: params.intent,\n height: params.height,\n }));\n host.ensureMap(block.mapId, title);\n await host.writeMap({\n mapId: block.mapId,\n title,\n config: preparedConfig,\n selectedTable: table?.tableIdentity,\n });\n if (existingBlock) {\n await host.updateBlockMetadata({\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n caption,\n intent: params.intent,\n height: params.height,\n });\n }\n return {\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n mapId: block.mapId,\n selectedTable: table?.tableIdentity,\n created,\n message: created\n ? `Added ${artifactLabel} map block \"${title}\".`\n : `Updated ${artifactLabel} map block \"${title}\".`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createOrUpdateDeckMapResource.js","sourceRoot":"","sources":["../src/createOrUpdateDeckMapResource.ts"],"names":[],"mappings":"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","sourcesContent":["import type {DeckMapResource} from './DeckMapsSlice';\nimport {createDeckTableDatasetSql} from './datasets/tableDatasetSql';\nimport {isDeckMapTableDatasetSource, type DeckMapConfig} from './mapConfig';\nimport {\n getFirstDatasetSourceTableName,\n hasSqlOnlyDatasetSource,\n} from './datasetSourceUtils';\nimport {assertDeckMapResourceConfig} from './mapResourceAuthoring';\nimport {\n applyDeckMapPointBinding,\n type DeckMapConfigColumn,\n type DeckMapPointBinding,\n} from './mapConfigUtils';\n\n/**\n * Host callbacks used to coordinate a durable Deck map resource with its block\n * document container, table registry, and optional config preparation.\n */\nexport type CreateOrUpdateDeckMapResourceHost = {\n ensureBlockDocument: (blockDocumentId: string) => void;\n findMapBlock: (\n blockDocumentId: string,\n mapId: string,\n ) => {blockId: string; mapId: string; caption?: string} | undefined;\n findMap: (mapId: string) => DeckMapResource | undefined;\n createMapBlock: (options: {\n blockDocumentId: string;\n mapId: string;\n title: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => Promise<{blockId: string; mapId: string}>;\n updateBlockMetadata: (options: {\n blockDocumentId: string;\n blockId: string;\n caption?: string;\n intent?: string;\n height?: number;\n }) => void | Promise<void>;\n ensureMap: (mapId: string, title: string) => void;\n writeMap: (options: {\n mapId: string;\n title: string;\n config: DeckMapConfig;\n selectedTable?: string;\n }) => void | Promise<void>;\n findTable: (\n tableName: string,\n ) =>\n | {tableIdentity: string; columns: readonly DeckMapConfigColumn[]}\n | undefined;\n prepareConfig?: (options: {\n config: DeckMapConfig;\n existingMapConfig?: DeckMapConfig;\n tableName?: string;\n replaceLayers?: boolean;\n replaceDatasets?: boolean;\n }) => DeckMapConfig | Promise<DeckMapConfig>;\n};\n\n/** Input for creating or updating a Deck map resource and its owning block. */\nexport type CreateOrUpdateDeckMapResourceParams = {\n blockDocumentId: string;\n config: DeckMapConfig;\n /** Generates canonical point geometry from structured lon/lat provenance. */\n pointBinding?: DeckMapPointBinding;\n mapId?: string;\n tableName?: string;\n title?: string;\n caption?: string;\n intent?: string;\n height?: number;\n /** Treat `config.spec.layers` as the complete replacement layer list. */\n replaceLayers?: boolean;\n /** Treat `config.datasets` as the complete replacement dataset registry. */\n replaceDatasets?: boolean;\n requireTableNameForSqlOnlyUpdate?: boolean;\n artifactLabel?: string;\n createMapId?: () => string;\n missingMapBlockBehavior?: 'throw' | 'create';\n};\n\n/** Result identities and resolved table selection from a map resource write. */\nexport type CreateOrUpdateDeckMapResourceResult = {\n blockDocumentId: string;\n blockId: string;\n mapId: string;\n selectedTable?: string;\n message: string;\n created: boolean;\n};\n\nfunction resolveTableDatasetSources(\n host: Pick<CreateOrUpdateDeckMapResourceHost, 'findTable'>,\n config: DeckMapConfig,\n): DeckMapConfig {\n let changed = false;\n const datasets = Object.fromEntries(\n Object.entries(config.datasets).map(([datasetId, dataset]) => {\n const source = dataset.source;\n if (!isDeckMapTableDatasetSource(source)) return [datasetId, dataset];\n\n const table = host.findTable(source.tableName);\n if (!table) {\n throw new Error(\n `Dataset \"${datasetId}\" table \"${source.tableName}\" was not found.`,\n );\n }\n const canonicalSource = {\n ...source,\n tableName: table.tableIdentity,\n };\n createDeckTableDatasetSql(canonicalSource);\n if (canonicalSource.tableName === source.tableName) {\n return [datasetId, dataset];\n }\n changed = true;\n return [datasetId, {...dataset, source: canonicalSource}];\n }),\n );\n return changed ? {...config, datasets} : config;\n}\n\n/** Resource-native document map orchestration with metadata-after-map-write ordering. */\nexport async function createOrUpdateDeckMapResource(\n host: CreateOrUpdateDeckMapResourceHost,\n params: CreateOrUpdateDeckMapResourceParams,\n): Promise<CreateOrUpdateDeckMapResourceResult> {\n const artifactLabel = params.artifactLabel ?? 'block document';\n host.ensureBlockDocument(params.blockDocumentId);\n const existingBlock = params.mapId\n ? host.findMapBlock(params.blockDocumentId, params.mapId)\n : undefined;\n const missingBehavior = params.missingMapBlockBehavior ?? 'throw';\n if (params.mapId && !existingBlock && missingBehavior === 'throw') {\n throw new Error(\n `${artifactLabel} map block ${params.mapId} was not found in ${params.blockDocumentId}`,\n );\n }\n const mapId = existingBlock?.mapId ?? params.mapId ?? params.createMapId?.();\n if (!mapId) throw new Error('mapId is required when creating a map block');\n\n const existingMap = host.findMap(mapId);\n const requestedTable =\n params.tableName ?? getFirstDatasetSourceTableName(params.config);\n const preparedConfig = host.prepareConfig\n ? await host.prepareConfig({\n config: params.config,\n existingMapConfig: existingMap?.config,\n tableName: requestedTable,\n replaceLayers: params.replaceLayers,\n replaceDatasets: params.replaceDatasets,\n })\n : params.config;\n const pointBindingDataset = params.pointBinding\n ? preparedConfig.datasets[params.pointBinding.dataset.trim()]\n : undefined;\n const pointBindingTable = isDeckMapTableDatasetSource(\n pointBindingDataset?.source,\n )\n ? host.findTable(pointBindingDataset.source.tableName)\n : undefined;\n if (\n params.pointBinding &&\n isDeckMapTableDatasetSource(pointBindingDataset?.source) &&\n !pointBindingTable\n ) {\n throw new Error(\n `Dataset \"${params.pointBinding.dataset.trim()}\" table \"${pointBindingDataset.source.tableName}\" was not found.`,\n );\n }\n const pointBoundConfig = params.pointBinding\n ? applyDeckMapPointBinding({\n config: preparedConfig,\n pointBinding: params.pointBinding,\n sourceColumns: pointBindingTable?.columns ?? [],\n })\n : preparedConfig;\n const resolvedConfig = resolveTableDatasetSources(host, pointBoundConfig);\n assertDeckMapResourceConfig(resolvedConfig);\n const tableName =\n requestedTable ?? getFirstDatasetSourceTableName(resolvedConfig);\n if (\n (params.requireTableNameForSqlOnlyUpdate ?? true) &&\n existingBlock &&\n !tableName &&\n hasSqlOnlyDatasetSource(params.config)\n ) {\n throw new Error(\n `tableName is required when updating a ${artifactLabel} map block with SQL-only dataset sources.`,\n );\n }\n const table = tableName ? host.findTable(tableName) : undefined;\n if (tableName && !table)\n throw new Error(`Table \"${tableName}\" was not found.`);\n const tableDatasetCount = Object.values(resolvedConfig.datasets).filter(\n (dataset) => isDeckMapTableDatasetSource(dataset.source),\n ).length;\n if (\n params.pointBinding &&\n tableDatasetCount === 1 &&\n pointBindingTable &&\n table &&\n pointBindingTable.tableIdentity !== table.tableIdentity\n ) {\n throw new Error(\n `Point binding dataset \"${params.pointBinding.dataset.trim()}\" resolves to table \"${pointBindingTable.tableIdentity}\", but selected table \"${table.tableIdentity}\" would override it.`,\n );\n }\n\n const caption =\n params.caption?.trim() ||\n params.title?.trim() ||\n existingBlock?.caption?.trim() ||\n existingMap?.title?.trim() ||\n 'Map';\n const title = params.title?.trim() || caption;\n const created = !existingBlock;\n const block =\n existingBlock ??\n (await host.createMapBlock({\n blockDocumentId: params.blockDocumentId,\n mapId,\n title,\n caption,\n intent: params.intent,\n height: params.height,\n }));\n host.ensureMap(block.mapId, title);\n await host.writeMap({\n mapId: block.mapId,\n title,\n config: resolvedConfig,\n selectedTable: table?.tableIdentity,\n });\n if (existingBlock) {\n await host.updateBlockMetadata({\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n caption,\n intent: params.intent,\n height: params.height,\n });\n }\n return {\n blockDocumentId: params.blockDocumentId,\n blockId: block.blockId,\n mapId: block.mapId,\n selectedTable: table?.tableIdentity,\n created,\n message: created\n ? `Added ${artifactLabel} map block \"${title}\".`\n : `Updated ${artifactLabel} map block \"${title}\".`,\n };\n}\n"]}
|
|
@@ -26,10 +26,9 @@ type PreparedDatasetStoreState = {
|
|
|
26
26
|
/**
|
|
27
27
|
* Ensure a cache entry exists for the given dataset key.
|
|
28
28
|
*
|
|
29
|
-
* If an entry already exists, this is a no-op
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* stores the resulting `ready` or `error` state.
|
|
29
|
+
* If an entry already exists, this is a no-op besides refreshing the
|
|
30
|
+
* in-place LRU timestamp. Subscribers are not notified: a cache hit is not
|
|
31
|
+
* a dataset change, and notifying would rebuild every mounted map's layers.
|
|
33
32
|
*/
|
|
34
33
|
ensureEntry: (options: {
|
|
35
34
|
cacheKey: string;
|
|
@@ -1 +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;
|
|
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;AAUlB,OAAO,KAAK,EACV,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAQjB;;;;;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;;;;;;OAMG;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,yDA8Q1C;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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createStore } from 'zustand/vanilla';
|
|
2
2
|
import { prepareDeckDataset } from '../prepare/prepareDeckDataset';
|
|
3
3
|
import { isSqlDatasetInput, isTableDatasetInput, } from '../types';
|
|
4
|
-
import { DEFAULT_MAX_PREPARED_DATASET_ENTRIES, cloneEntryWithConsumers, evictLruEntries, nextAccessTimestamp, resolvePreparedDatasetCacheKey,
|
|
4
|
+
import { DEFAULT_MAX_PREPARED_DATASET_ENTRIES, cloneEntryWithConsumers, evictLruEntries, nextAccessTimestamp, resolvePreparedDatasetCacheKey, } from './helpers';
|
|
5
5
|
import { resolveArrowTable } from './normalizeDatasets';
|
|
6
6
|
import { createDeckTableDatasetSql } from './tableDatasetSql';
|
|
7
7
|
import { createDescribeDatasetSql, geometryColumnsNeedingWkbWrap, parseDescribeSqlColumns, wrapSqlGeometryColumnsAsWkb, } from './wrapGeometryAsWkb';
|
|
@@ -38,13 +38,9 @@ export function createPreparedDatasetStore(options = {}) {
|
|
|
38
38
|
const existing = get().entries[cacheKey];
|
|
39
39
|
if (existing) {
|
|
40
40
|
if (existing.status !== 'loading') {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
...state.entries,
|
|
45
|
-
[cacheKey]: touchEntry(existing),
|
|
46
|
-
},
|
|
47
|
-
}));
|
|
41
|
+
// Mutate the timestamp in place so LRU still works without replacing
|
|
42
|
+
// `entries` and forcing every DeckJsonMap to reconvert layers.
|
|
43
|
+
existing.lastAccessedAt = nextAccessTimestamp();
|
|
48
44
|
}
|
|
49
45
|
return;
|
|
50
46
|
}
|
|
@@ -1 +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';\nimport {\n createDescribeDatasetSql,\n geometryColumnsNeedingWkbWrap,\n parseDescribeSqlColumns,\n wrapSqlGeometryColumnsAsWkb,\n} from './wrapGeometryAsWkb';\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 let geometryEncodingHint = input.geometryEncodingHint;\n if (\n !table &&\n (isSqlDatasetInput(input) || isTableDatasetInput(input))\n ) {\n const baseSql = isSqlDatasetInput(input)\n ? input.sqlQuery\n : createDeckTableDatasetSql(input);\n\n // Probe DuckDB logical types and project native GEOMETRY columns\n // through ST_AsWKB so prepare/decode never sees undecodable blobs.\n // Authored SQL is left intact — the wrap is a pipeline outer query.\n let sql = baseSql;\n try {\n const describeHandle = await executeSql(\n createDescribeDatasetSql(baseSql),\n );\n if (describeHandle) {\n const describeTable = await describeHandle;\n const geometryColumns = geometryColumnsNeedingWkbWrap(\n parseDescribeSqlColumns(describeTable),\n );\n const wrapped = wrapSqlGeometryColumnsAsWkb(\n baseSql,\n geometryColumns,\n );\n if (wrapped) {\n sql = wrapped;\n // Only force the dataset-level hint to WKB when the configured\n // geometry column was among the wrapped columns (or unset).\n // An unrelated native GEOMETRY column must not make a WKT /\n // GeoArrow geometryColumn decode as WKB.\n const resolvedGeom = input.geometryColumn;\n if (!resolvedGeom || geometryColumns.includes(resolvedGeom)) {\n geometryEncodingHint = 'wkb';\n }\n }\n }\n } catch {\n // If DESCRIBE fails (e.g. missing spatial), fall through to the\n // original SQL — prepare still surfaces decode errors.\n }\n\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,\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"]}
|
|
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} from './helpers';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport {createDeckTableDatasetSql} from './tableDatasetSql';\nimport type {\n PreparedDatasetCacheEntry,\n PreparedDatasetStoreOptions,\n} from './types';\nimport {\n createDescribeDatasetSql,\n geometryColumnsNeedingWkbWrap,\n parseDescribeSqlColumns,\n wrapSqlGeometryColumnsAsWkb,\n} from './wrapGeometryAsWkb';\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 besides refreshing the\n * in-place LRU timestamp. Subscribers are not notified: a cache hit is not\n * a dataset change, and notifying would rebuild every mounted map's layers.\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 // Mutate the timestamp in place so LRU still works without replacing\n // `entries` and forcing every DeckJsonMap to reconvert layers.\n existing.lastAccessedAt = nextAccessTimestamp();\n }\n return;\n }\n\n const promise = Promise.resolve().then(async () => {\n try {\n let table = resolveArrowTable(input);\n let geometryEncodingHint = input.geometryEncodingHint;\n if (\n !table &&\n (isSqlDatasetInput(input) || isTableDatasetInput(input))\n ) {\n const baseSql = isSqlDatasetInput(input)\n ? input.sqlQuery\n : createDeckTableDatasetSql(input);\n\n // Probe DuckDB logical types and project native GEOMETRY columns\n // through ST_AsWKB so prepare/decode never sees undecodable blobs.\n // Authored SQL is left intact — the wrap is a pipeline outer query.\n let sql = baseSql;\n try {\n const describeHandle = await executeSql(\n createDescribeDatasetSql(baseSql),\n );\n if (describeHandle) {\n const describeTable = await describeHandle;\n const geometryColumns = geometryColumnsNeedingWkbWrap(\n parseDescribeSqlColumns(describeTable),\n );\n const wrapped = wrapSqlGeometryColumnsAsWkb(\n baseSql,\n geometryColumns,\n );\n if (wrapped) {\n sql = wrapped;\n // Only force the dataset-level hint to WKB when the configured\n // geometry column was among the wrapped columns (or unset).\n // An unrelated native GEOMETRY column must not make a WKT /\n // GeoArrow geometryColumn decode as WKB.\n const resolvedGeom = input.geometryColumn;\n if (!resolvedGeom || geometryColumns.includes(resolvedGeom)) {\n geometryEncodingHint = 'wkb';\n }\n }\n }\n } catch {\n // If DESCRIBE fails (e.g. missing spatial), fall through to the\n // original SQL — prepare still surfaces decode errors.\n }\n\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,\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"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as arrow from 'apache-arrow';
|
|
2
|
-
import { type DeckDatasetInput } from '../types';
|
|
2
|
+
import { type DeckDatasetInput, type PreparedDeckDatasetState } from '../types';
|
|
3
3
|
import type { PreparedDatasetCacheEntry } from './types';
|
|
4
4
|
export declare const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;
|
|
5
5
|
/** Return a monotonic access timestamp used by the prepared-dataset LRU. */
|
|
@@ -19,7 +19,44 @@ export declare function getTableIdentity(table: arrow.Table): string;
|
|
|
19
19
|
* prepared results across different database instances.
|
|
20
20
|
*/
|
|
21
21
|
export declare function getSqlSourceIdentity(sqlSourceIdentity: object): string;
|
|
22
|
-
export declare function buildGeometryKey(
|
|
22
|
+
export declare function buildGeometryKey(options: {
|
|
23
|
+
geometryColumn?: string;
|
|
24
|
+
geometryEncodingHint?: string;
|
|
25
|
+
}): string;
|
|
26
|
+
/**
|
|
27
|
+
* Content identity for one dataset input, ignoring object-wrapper identity.
|
|
28
|
+
*
|
|
29
|
+
* Spec-only updates (slider opacity, radius, etc.) often recreate
|
|
30
|
+
* `{ tableName, transformSql }` literals even though the query did not change.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getDatasetInputFingerprint(input: DeckDatasetInput): string;
|
|
33
|
+
/** Sorted content identity for a dataset registry. */
|
|
34
|
+
export declare function getDatasetRegistryFingerprint(datasets: Record<string, DeckDatasetInput>): string;
|
|
35
|
+
/**
|
|
36
|
+
* Content equality for one dataset input, ignoring object-wrapper identity.
|
|
37
|
+
*
|
|
38
|
+
* Implemented via {@link getDatasetInputFingerprint} so normalization stays
|
|
39
|
+
* identical to the fingerprint path (`''` vs `undefined`, pending Arrow, etc.).
|
|
40
|
+
* A hand-rolled field compare previously treated those differently and caused
|
|
41
|
+
* `useStableDatasets` to churn, which desynced MapLibre from deck layers.
|
|
42
|
+
*/
|
|
43
|
+
export declare function areDatasetInputsEqual(left: DeckDatasetInput, right: DeckDatasetInput): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Content equality for a dataset registry, ignoring object-wrapper identity.
|
|
46
|
+
*
|
|
47
|
+
* Prefer this at call sites that want a boolean compare; it is fingerprint-
|
|
48
|
+
* backed so behavior matches {@link getDatasetRegistryFingerprint}.
|
|
49
|
+
*/
|
|
50
|
+
export declare function areDatasetRegistriesEqual(left: Record<string, DeckDatasetInput>, right: Record<string, DeckDatasetInput>): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Identity of prepared dataset *payloads*, not the wrapper object.
|
|
53
|
+
*
|
|
54
|
+
* Used so JSONConverter is not rebuilt when a new `datasetStates` record
|
|
55
|
+
* points at the same prepared tables. Geometry column and encoding are part
|
|
56
|
+
* of the identity so two cache entries that share an Arrow table but were
|
|
57
|
+
* prepared with different geometry options do not look interchangeable.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getPreparedDatasetStatesIdentity(datasetStates: Record<string, PreparedDeckDatasetState>): string;
|
|
23
60
|
/**
|
|
24
61
|
* Build the canonical cache key for one dataset input.
|
|
25
62
|
*
|
|
@@ -1 +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,
|
|
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,EAIL,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC9B,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,OAAO,EAAE;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,GAAG,MAAM,CAET;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAY1E;AAED,sDAAsD;AACtD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACzC,MAAM,CAQR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACtC,OAAO,CAOT;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GACtD,MAAM,CAsBR;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"}
|
package/dist/datasets/helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isSqlDatasetInput, isTableDatasetInput, } from '../types';
|
|
1
|
+
import { isArrowTableDatasetInput, isSqlDatasetInput, isTableDatasetInput, } from '../types';
|
|
2
2
|
import { resolveArrowTable } from './normalizeDatasets';
|
|
3
3
|
export const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;
|
|
4
4
|
let nextDatasetAccess = 0;
|
|
@@ -44,8 +44,91 @@ export function getSqlSourceIdentity(sqlSourceIdentity) {
|
|
|
44
44
|
sqlSourceIdentities.set(sqlSourceIdentity, identity);
|
|
45
45
|
return identity;
|
|
46
46
|
}
|
|
47
|
-
export function buildGeometryKey(
|
|
48
|
-
return `${
|
|
47
|
+
export function buildGeometryKey(options) {
|
|
48
|
+
return `${options.geometryColumn ?? ''}\u0001${options.geometryEncodingHint ?? ''}`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Content identity for one dataset input, ignoring object-wrapper identity.
|
|
52
|
+
*
|
|
53
|
+
* Spec-only updates (slider opacity, radius, etc.) often recreate
|
|
54
|
+
* `{ tableName, transformSql }` literals even though the query did not change.
|
|
55
|
+
*/
|
|
56
|
+
export function getDatasetInputFingerprint(input) {
|
|
57
|
+
if (isSqlDatasetInput(input)) {
|
|
58
|
+
return `sql\u0001${input.sqlQuery}\u0001${buildGeometryKey(input)}`;
|
|
59
|
+
}
|
|
60
|
+
if (isTableDatasetInput(input)) {
|
|
61
|
+
return `table\u0001${input.tableName}\u0001${input.transformSql ?? ''}\u0001${buildGeometryKey(input)}`;
|
|
62
|
+
}
|
|
63
|
+
if (isArrowTableDatasetInput(input)) {
|
|
64
|
+
const table = resolveArrowTable(input);
|
|
65
|
+
return `arrow\u0001${table ? getTableIdentity(table) : 'pending'}\u0001${buildGeometryKey(input)}`;
|
|
66
|
+
}
|
|
67
|
+
return 'unknown';
|
|
68
|
+
}
|
|
69
|
+
/** Sorted content identity for a dataset registry. */
|
|
70
|
+
export function getDatasetRegistryFingerprint(datasets) {
|
|
71
|
+
return Object.entries(datasets)
|
|
72
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
73
|
+
.map(([datasetId, input]) => `${datasetId}\u0001${getDatasetInputFingerprint(input)}`)
|
|
74
|
+
.join('\u0002');
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Content equality for one dataset input, ignoring object-wrapper identity.
|
|
78
|
+
*
|
|
79
|
+
* Implemented via {@link getDatasetInputFingerprint} so normalization stays
|
|
80
|
+
* identical to the fingerprint path (`''` vs `undefined`, pending Arrow, etc.).
|
|
81
|
+
* A hand-rolled field compare previously treated those differently and caused
|
|
82
|
+
* `useStableDatasets` to churn, which desynced MapLibre from deck layers.
|
|
83
|
+
*/
|
|
84
|
+
export function areDatasetInputsEqual(left, right) {
|
|
85
|
+
if (left === right) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return getDatasetInputFingerprint(left) === getDatasetInputFingerprint(right);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Content equality for a dataset registry, ignoring object-wrapper identity.
|
|
92
|
+
*
|
|
93
|
+
* Prefer this at call sites that want a boolean compare; it is fingerprint-
|
|
94
|
+
* backed so behavior matches {@link getDatasetRegistryFingerprint}.
|
|
95
|
+
*/
|
|
96
|
+
export function areDatasetRegistriesEqual(left, right) {
|
|
97
|
+
if (left === right) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return (getDatasetRegistryFingerprint(left) === getDatasetRegistryFingerprint(right));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Identity of prepared dataset *payloads*, not the wrapper object.
|
|
104
|
+
*
|
|
105
|
+
* Used so JSONConverter is not rebuilt when a new `datasetStates` record
|
|
106
|
+
* points at the same prepared tables. Geometry column and encoding are part
|
|
107
|
+
* of the identity so two cache entries that share an Arrow table but were
|
|
108
|
+
* prepared with different geometry options do not look interchangeable.
|
|
109
|
+
*/
|
|
110
|
+
export function getPreparedDatasetStatesIdentity(datasetStates) {
|
|
111
|
+
return Object.keys(datasetStates)
|
|
112
|
+
.sort()
|
|
113
|
+
.map((datasetId) => {
|
|
114
|
+
const state = datasetStates[datasetId];
|
|
115
|
+
if (state.status === 'ready') {
|
|
116
|
+
return [
|
|
117
|
+
datasetId,
|
|
118
|
+
'ready',
|
|
119
|
+
getTableIdentity(state.prepared.table),
|
|
120
|
+
buildGeometryKey({
|
|
121
|
+
geometryColumn: state.prepared.datasetGeometryColumn,
|
|
122
|
+
geometryEncodingHint: state.prepared.datasetGeometryEncodingHint,
|
|
123
|
+
}),
|
|
124
|
+
].join(':');
|
|
125
|
+
}
|
|
126
|
+
if (state.status === 'error') {
|
|
127
|
+
return `${datasetId}:error:${state.error.message}`;
|
|
128
|
+
}
|
|
129
|
+
return `${datasetId}:${state.status}`;
|
|
130
|
+
})
|
|
131
|
+
.join('|');
|
|
49
132
|
}
|
|
50
133
|
/**
|
|
51
134
|
* Build the canonical cache key for one dataset input.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/datasets/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport {\n isSqlDatasetInput,\n isTableDatasetInput,\n type DeckDatasetInput,\n} from '../types';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport type {PreparedDatasetCacheEntry} from './types';\n\nexport const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;\n\nlet nextDatasetAccess = 0;\nlet nextTableIdentity = 0;\nlet nextSqlSourceIdentity = 0;\n\nconst tableIdentities = new WeakMap<arrow.Table, string>();\nconst sqlSourceIdentities = new WeakMap<object, string>();\n\n/** Return a monotonic access timestamp used by the prepared-dataset LRU. */\nexport function nextAccessTimestamp(): number {\n nextDatasetAccess += 1;\n return nextDatasetAccess;\n}\n\n/**\n * Assign a stable cache identity to an Arrow table object.\n *\n * Table identities are stored in a `WeakMap` so this cache does not extend the\n * lifetime of tables once they are no longer referenced elsewhere.\n */\nexport function getTableIdentity(table: arrow.Table): string {\n const cached = tableIdentities.get(table);\n if (cached) {\n return cached;\n }\n\n nextTableIdentity += 1;\n const identity = `table:${nextTableIdentity}`;\n tableIdentities.set(table, identity);\n return identity;\n}\n\n/**\n * Assign a stable cache identity to the current SQL source object.\n *\n * For SQL datasets we include the upstream DuckDB connector identity in the\n * cache key so two rooms using the same SQL text do not accidentally share\n * prepared results across different database instances.\n */\nexport function getSqlSourceIdentity(sqlSourceIdentity: object): string {\n const cached = sqlSourceIdentities.get(sqlSourceIdentity);\n if (cached) {\n return cached;\n }\n\n nextSqlSourceIdentity += 1;\n const identity = `sql-source:${nextSqlSourceIdentity}`;\n sqlSourceIdentities.set(sqlSourceIdentity, identity);\n return identity;\n}\n\nexport function buildGeometryKey(input: DeckDatasetInput): string {\n return `${input.geometryColumn ?? ''}\\u0001${input.geometryEncodingHint ?? ''}`;\n}\n\n/**\n * Build the canonical cache key for one dataset input.\n *\n * The key intentionally ignores the user-facing dataset id and instead uses\n * the underlying data identity:\n *\n * - SQL/table datasets: DuckDB connector identity + compiled SQL + geometry options\n * - Arrow datasets: table object identity + geometry options\n *\n * Unresolved Arrow inputs (`arrowTable: undefined`) return `undefined`, which\n * signals that the dataset should remain in `loading` until a table exists.\n */\nexport function resolvePreparedDatasetCacheKey(options: {\n input: DeckDatasetInput;\n sqlSourceIdentity?: object;\n}): string | undefined {\n const {input, sqlSourceIdentity} = options;\n\n if (isSqlDatasetInput(input) || isTableDatasetInput(input)) {\n if (!sqlSourceIdentity) {\n throw new Error(\n 'SQL-backed dataset cache keys require a sqlSourceIdentity object.',\n );\n }\n\n if (isTableDatasetInput(input)) {\n return [\n 'table',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.tableName,\n input.transformSql ?? '',\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n return [\n 'sql',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.sqlQuery,\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n const table = resolveArrowTable(input);\n if (!table) {\n return undefined;\n }\n\n return ['arrow', getTableIdentity(table), buildGeometryKey(input)].join(\n '\\u0001',\n );\n}\n\n/**\n * Clone a cache entry while replacing its consumer set and refreshing the\n * access timestamp.\n *\n * This keeps the discriminated union shape intact while centralizing the\n * bookkeeping needed by consumer reconciliation and LRU tracking.\n */\nexport function cloneEntryWithConsumers(\n entry: PreparedDatasetCacheEntry,\n consumers: Set<string>,\n): PreparedDatasetCacheEntry {\n const lastAccessedAt = nextAccessTimestamp();\n\n if (entry.status === 'loading') {\n return {\n status: 'loading',\n promise: entry.promise,\n consumers,\n lastAccessedAt,\n };\n }\n\n if (entry.status === 'ready') {\n return {\n status: 'ready',\n prepared: entry.prepared,\n consumers,\n lastAccessedAt,\n };\n }\n\n return {\n status: 'error',\n error: entry.error,\n consumers,\n lastAccessedAt,\n };\n}\n\n/** Mark an entry as recently used without changing its lifecycle payload. */\nexport function touchEntry(\n entry: PreparedDatasetCacheEntry,\n): PreparedDatasetCacheEntry {\n return cloneEntryWithConsumers(entry, new Set(entry.consumers));\n}\n\n/**\n * Evict least-recently-used settled entries when the cache exceeds capacity.\n *\n * Only `ready` and `error` entries participate in eviction. `loading` entries\n * are preserved so in-flight work is not discarded, and referenced entries are\n * preserved so active maps never lose their prepared data mid-render.\n */\nexport function evictLruEntries(\n entries: Record<string, PreparedDatasetCacheEntry>,\n maxEntries: number,\n): Record<string, PreparedDatasetCacheEntry> {\n const settledEntries = Object.entries(entries).filter(\n ([, entry]) => entry.status !== 'loading',\n );\n\n if (settledEntries.length <= maxEntries) {\n return entries;\n }\n\n const evictable = settledEntries\n .filter(([, entry]) => entry.consumers.size === 0)\n .sort(([, left], [, right]) => left.lastAccessedAt - right.lastAccessedAt);\n\n if (evictable.length === 0) {\n return entries;\n }\n\n const nextEntries = {...entries};\n let settledCount = settledEntries.length;\n\n for (const [cacheKey] of evictable) {\n if (settledCount <= maxEntries) {\n break;\n }\n\n delete nextEntries[cacheKey];\n settledCount -= 1;\n }\n\n return nextEntries;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/datasets/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as arrow from 'apache-arrow';\nimport {\n isArrowTableDatasetInput,\n isSqlDatasetInput,\n isTableDatasetInput,\n type DeckDatasetInput,\n type PreparedDeckDatasetState,\n} from '../types';\nimport {resolveArrowTable} from './normalizeDatasets';\nimport type {PreparedDatasetCacheEntry} from './types';\n\nexport const DEFAULT_MAX_PREPARED_DATASET_ENTRIES = 20;\n\nlet nextDatasetAccess = 0;\nlet nextTableIdentity = 0;\nlet nextSqlSourceIdentity = 0;\n\nconst tableIdentities = new WeakMap<arrow.Table, string>();\nconst sqlSourceIdentities = new WeakMap<object, string>();\n\n/** Return a monotonic access timestamp used by the prepared-dataset LRU. */\nexport function nextAccessTimestamp(): number {\n nextDatasetAccess += 1;\n return nextDatasetAccess;\n}\n\n/**\n * Assign a stable cache identity to an Arrow table object.\n *\n * Table identities are stored in a `WeakMap` so this cache does not extend the\n * lifetime of tables once they are no longer referenced elsewhere.\n */\nexport function getTableIdentity(table: arrow.Table): string {\n const cached = tableIdentities.get(table);\n if (cached) {\n return cached;\n }\n\n nextTableIdentity += 1;\n const identity = `table:${nextTableIdentity}`;\n tableIdentities.set(table, identity);\n return identity;\n}\n\n/**\n * Assign a stable cache identity to the current SQL source object.\n *\n * For SQL datasets we include the upstream DuckDB connector identity in the\n * cache key so two rooms using the same SQL text do not accidentally share\n * prepared results across different database instances.\n */\nexport function getSqlSourceIdentity(sqlSourceIdentity: object): string {\n const cached = sqlSourceIdentities.get(sqlSourceIdentity);\n if (cached) {\n return cached;\n }\n\n nextSqlSourceIdentity += 1;\n const identity = `sql-source:${nextSqlSourceIdentity}`;\n sqlSourceIdentities.set(sqlSourceIdentity, identity);\n return identity;\n}\n\nexport function buildGeometryKey(options: {\n geometryColumn?: string;\n geometryEncodingHint?: string;\n}): string {\n return `${options.geometryColumn ?? ''}\\u0001${options.geometryEncodingHint ?? ''}`;\n}\n\n/**\n * Content identity for one dataset input, ignoring object-wrapper identity.\n *\n * Spec-only updates (slider opacity, radius, etc.) often recreate\n * `{ tableName, transformSql }` literals even though the query did not change.\n */\nexport function getDatasetInputFingerprint(input: DeckDatasetInput): string {\n if (isSqlDatasetInput(input)) {\n return `sql\\u0001${input.sqlQuery}\\u0001${buildGeometryKey(input)}`;\n }\n if (isTableDatasetInput(input)) {\n return `table\\u0001${input.tableName}\\u0001${input.transformSql ?? ''}\\u0001${buildGeometryKey(input)}`;\n }\n if (isArrowTableDatasetInput(input)) {\n const table = resolveArrowTable(input);\n return `arrow\\u0001${table ? getTableIdentity(table) : 'pending'}\\u0001${buildGeometryKey(input)}`;\n }\n return 'unknown';\n}\n\n/** Sorted content identity for a dataset registry. */\nexport function getDatasetRegistryFingerprint(\n datasets: Record<string, DeckDatasetInput>,\n): string {\n return Object.entries(datasets)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(\n ([datasetId, input]) =>\n `${datasetId}\\u0001${getDatasetInputFingerprint(input)}`,\n )\n .join('\\u0002');\n}\n\n/**\n * Content equality for one dataset input, ignoring object-wrapper identity.\n *\n * Implemented via {@link getDatasetInputFingerprint} so normalization stays\n * identical to the fingerprint path (`''` vs `undefined`, pending Arrow, etc.).\n * A hand-rolled field compare previously treated those differently and caused\n * `useStableDatasets` to churn, which desynced MapLibre from deck layers.\n */\nexport function areDatasetInputsEqual(\n left: DeckDatasetInput,\n right: DeckDatasetInput,\n): boolean {\n if (left === right) {\n return true;\n }\n return getDatasetInputFingerprint(left) === getDatasetInputFingerprint(right);\n}\n\n/**\n * Content equality for a dataset registry, ignoring object-wrapper identity.\n *\n * Prefer this at call sites that want a boolean compare; it is fingerprint-\n * backed so behavior matches {@link getDatasetRegistryFingerprint}.\n */\nexport function areDatasetRegistriesEqual(\n left: Record<string, DeckDatasetInput>,\n right: Record<string, DeckDatasetInput>,\n): boolean {\n if (left === right) {\n return true;\n }\n return (\n getDatasetRegistryFingerprint(left) === getDatasetRegistryFingerprint(right)\n );\n}\n\n/**\n * Identity of prepared dataset *payloads*, not the wrapper object.\n *\n * Used so JSONConverter is not rebuilt when a new `datasetStates` record\n * points at the same prepared tables. Geometry column and encoding are part\n * of the identity so two cache entries that share an Arrow table but were\n * prepared with different geometry options do not look interchangeable.\n */\nexport function getPreparedDatasetStatesIdentity(\n datasetStates: Record<string, PreparedDeckDatasetState>,\n): string {\n return Object.keys(datasetStates)\n .sort()\n .map((datasetId) => {\n const state = datasetStates[datasetId]!;\n if (state.status === 'ready') {\n return [\n datasetId,\n 'ready',\n getTableIdentity(state.prepared.table),\n buildGeometryKey({\n geometryColumn: state.prepared.datasetGeometryColumn,\n geometryEncodingHint: state.prepared.datasetGeometryEncodingHint,\n }),\n ].join(':');\n }\n if (state.status === 'error') {\n return `${datasetId}:error:${state.error.message}`;\n }\n return `${datasetId}:${state.status}`;\n })\n .join('|');\n}\n\n/**\n * Build the canonical cache key for one dataset input.\n *\n * The key intentionally ignores the user-facing dataset id and instead uses\n * the underlying data identity:\n *\n * - SQL/table datasets: DuckDB connector identity + compiled SQL + geometry options\n * - Arrow datasets: table object identity + geometry options\n *\n * Unresolved Arrow inputs (`arrowTable: undefined`) return `undefined`, which\n * signals that the dataset should remain in `loading` until a table exists.\n */\nexport function resolvePreparedDatasetCacheKey(options: {\n input: DeckDatasetInput;\n sqlSourceIdentity?: object;\n}): string | undefined {\n const {input, sqlSourceIdentity} = options;\n\n if (isSqlDatasetInput(input) || isTableDatasetInput(input)) {\n if (!sqlSourceIdentity) {\n throw new Error(\n 'SQL-backed dataset cache keys require a sqlSourceIdentity object.',\n );\n }\n\n if (isTableDatasetInput(input)) {\n return [\n 'table',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.tableName,\n input.transformSql ?? '',\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n return [\n 'sql',\n getSqlSourceIdentity(sqlSourceIdentity),\n input.sqlQuery,\n buildGeometryKey(input),\n ].join('\\u0001');\n }\n\n const table = resolveArrowTable(input);\n if (!table) {\n return undefined;\n }\n\n return ['arrow', getTableIdentity(table), buildGeometryKey(input)].join(\n '\\u0001',\n );\n}\n\n/**\n * Clone a cache entry while replacing its consumer set and refreshing the\n * access timestamp.\n *\n * This keeps the discriminated union shape intact while centralizing the\n * bookkeeping needed by consumer reconciliation and LRU tracking.\n */\nexport function cloneEntryWithConsumers(\n entry: PreparedDatasetCacheEntry,\n consumers: Set<string>,\n): PreparedDatasetCacheEntry {\n const lastAccessedAt = nextAccessTimestamp();\n\n if (entry.status === 'loading') {\n return {\n status: 'loading',\n promise: entry.promise,\n consumers,\n lastAccessedAt,\n };\n }\n\n if (entry.status === 'ready') {\n return {\n status: 'ready',\n prepared: entry.prepared,\n consumers,\n lastAccessedAt,\n };\n }\n\n return {\n status: 'error',\n error: entry.error,\n consumers,\n lastAccessedAt,\n };\n}\n\n/** Mark an entry as recently used without changing its lifecycle payload. */\nexport function touchEntry(\n entry: PreparedDatasetCacheEntry,\n): PreparedDatasetCacheEntry {\n return cloneEntryWithConsumers(entry, new Set(entry.consumers));\n}\n\n/**\n * Evict least-recently-used settled entries when the cache exceeds capacity.\n *\n * Only `ready` and `error` entries participate in eviction. `loading` entries\n * are preserved so in-flight work is not discarded, and referenced entries are\n * preserved so active maps never lose their prepared data mid-render.\n */\nexport function evictLruEntries(\n entries: Record<string, PreparedDatasetCacheEntry>,\n maxEntries: number,\n): Record<string, PreparedDatasetCacheEntry> {\n const settledEntries = Object.entries(entries).filter(\n ([, entry]) => entry.status !== 'loading',\n );\n\n if (settledEntries.length <= maxEntries) {\n return entries;\n }\n\n const evictable = settledEntries\n .filter(([, entry]) => entry.consumers.size === 0)\n .sort(([, left], [, right]) => left.lastAccessedAt - right.lastAccessedAt);\n\n if (evictable.length === 0) {\n return entries;\n }\n\n const nextEntries = {...entries};\n let settledCount = settledEntries.length;\n\n for (const [cacheKey] of evictable) {\n if (settledCount <= maxEntries) {\n break;\n }\n\n delete nextEntries[cacheKey];\n settledCount -= 1;\n }\n\n return nextEntries;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePreparedDatasetStates.d.ts","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usePreparedDatasetStates.d.ts","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,gBAAgB,EAAE,KAAK,wBAAwB,EAAC,MAAM,UAAU,CAAC;AA4B9E;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAsC1C"}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { useStoreWithDuckDb } from '@sqlrooms/duckdb';
|
|
2
2
|
import { useEffect, useId, useMemo, useState } from 'react';
|
|
3
3
|
import { useStore } from 'zustand';
|
|
4
|
-
import {
|
|
4
|
+
import { areDatasetRegistriesEqual, getPreparedDatasetStatesIdentity, } from './helpers';
|
|
5
5
|
import { preparedDatasetStore, resolvePreparedDeckDatasetStates, } from './PreparedDatasetStore';
|
|
6
6
|
/**
|
|
7
|
-
* Stabilize a `datasets` record so that a new object
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* actually changed. Uses Zustand's `shallow` to compare top-level keys
|
|
11
|
-
* and per-entry identity.
|
|
7
|
+
* Stabilize a `datasets` record so that a new object wrapper created on every
|
|
8
|
+
* render (for example after a slider-driven spec update) does not resync
|
|
9
|
+
* prepared data when the underlying query/table identity is unchanged.
|
|
12
10
|
*
|
|
13
11
|
* Implemented via the "adjusting state during rendering" pattern so the
|
|
14
12
|
* React compiler does not flag ref access during render.
|
|
15
13
|
*/
|
|
16
14
|
function useStableDatasets(datasets) {
|
|
17
15
|
const [stable, setStable] = useState(datasets);
|
|
18
|
-
if (!
|
|
16
|
+
if (!areDatasetRegistriesEqual(stable, datasets)) {
|
|
19
17
|
setStable(datasets);
|
|
20
18
|
}
|
|
21
19
|
return stable;
|
|
@@ -50,10 +48,16 @@ export function usePreparedDatasetStates(datasets) {
|
|
|
50
48
|
preparedDatasetStore.getState().removeConsumer(consumerId);
|
|
51
49
|
};
|
|
52
50
|
}, [connector, consumerId, stableDatasets, executeSql]);
|
|
53
|
-
|
|
51
|
+
const datasetStates = useMemo(() => resolvePreparedDeckDatasetStates({
|
|
54
52
|
datasets: stableDatasets,
|
|
55
53
|
entries,
|
|
56
54
|
sqlSourceIdentity: connector,
|
|
57
55
|
}), [connector, stableDatasets, entries]);
|
|
56
|
+
const [stableStates, setStableStates] = useState(datasetStates);
|
|
57
|
+
if (getPreparedDatasetStatesIdentity(stableStates) !==
|
|
58
|
+
getPreparedDatasetStatesIdentity(datasetStates)) {
|
|
59
|
+
setStableStates(datasetStates);
|
|
60
|
+
}
|
|
61
|
+
return stableStates;
|
|
58
62
|
}
|
|
59
63
|
//# sourceMappingURL=usePreparedDatasetStates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePreparedDatasetStates.js","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"usePreparedDatasetStates.js","sourceRoot":"","sources":["../../src/datasets/usePreparedDatasetStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEjC,OAAO,EACL,yBAAyB,EACzB,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;GAOG;AACH,SAAS,iBAAiB,CACxB,QAA0C;IAE1C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QACjD,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,QAA0C;IAE1C,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,KAAK,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEzE,SAAS,CAAC,GAAG,EAAE;QACb,oBAAoB,CAAC,QAAQ,EAAE,CAAC,uBAAuB,CAAC;YACtD,UAAU;YACV,QAAQ,EAAE,cAAc;YACxB,UAAU;YACV,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,oBAAoB,CAAC,QAAQ,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;IAExD,MAAM,aAAa,GAAG,OAAO,CAC3B,GAAG,EAAE,CACH,gCAAgC,CAAC;QAC/B,QAAQ,EAAE,cAAc;QACxB,OAAO;QACP,iBAAiB,EAAE,SAAS;KAC7B,CAAC,EACJ,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CACrC,CAAC;IAEF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChE,IACE,gCAAgC,CAAC,YAAY,CAAC;QAC9C,gCAAgC,CAAC,aAAa,CAAC,EAC/C,CAAC;QACD,eAAe,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import {useStoreWithDuckDb} from '@sqlrooms/duckdb';\nimport {useEffect, useId, useMemo, useState} from 'react';\nimport {useStore} from 'zustand';\nimport {type DeckDatasetInput, type PreparedDeckDatasetState} from '../types';\nimport {\n areDatasetRegistriesEqual,\n getPreparedDatasetStatesIdentity,\n} from './helpers';\nimport {\n preparedDatasetStore,\n resolvePreparedDeckDatasetStates,\n} from './PreparedDatasetStore';\n\n/**\n * Stabilize a `datasets` record so that a new object wrapper created on every\n * render (for example after a slider-driven spec update) does not resync\n * prepared data when the underlying query/table identity is unchanged.\n *\n * Implemented via the \"adjusting state during rendering\" pattern so the\n * React compiler does not flag ref access during render.\n */\nfunction useStableDatasets(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, DeckDatasetInput> {\n const [stable, setStable] = useState(datasets);\n if (!areDatasetRegistriesEqual(stable, datasets)) {\n setStable(datasets);\n }\n return stable;\n}\n\n/**\n * Subscribe a `DeckJsonMap` instance to prepared dataset state.\n *\n * This hook is intentionally a thin React adapter over the internal prepared\n * dataset store. The heavy work lives in the store so prepared geometry can be\n * reused across rerenders and even across multiple map instances, while the\n * hook itself focuses on subscribing React to the store and cleaning up the\n * consumer membership for this map instance.\n *\n * It preserves the current loading behavior for unresolved Arrow inputs, so a\n * caller can pass `{arrowTable: undefined}` and still render the basemap while\n * data is loading.\n */\nexport function usePreparedDatasetStates(\n datasets: Record<string, DeckDatasetInput>,\n): Record<string, PreparedDeckDatasetState> {\n const stableDatasets = useStableDatasets(datasets);\n const executeSql = useStoreWithDuckDb((state) => state.db.executeSql);\n const connector = useStoreWithDuckDb((state) => state.db.connector);\n const consumerId = useId();\n const entries = useStore(preparedDatasetStore, (state) => state.entries);\n\n useEffect(() => {\n preparedDatasetStore.getState().syncDatasetsForConsumer({\n consumerId,\n datasets: stableDatasets,\n executeSql,\n sqlSourceIdentity: connector,\n });\n\n return () => {\n preparedDatasetStore.getState().removeConsumer(consumerId);\n };\n }, [connector, consumerId, stableDatasets, executeSql]);\n\n const datasetStates = useMemo(\n () =>\n resolvePreparedDeckDatasetStates({\n datasets: stableDatasets,\n entries,\n sqlSourceIdentity: connector,\n }),\n [connector, stableDatasets, entries],\n );\n\n const [stableStates, setStableStates] = useState(datasetStates);\n if (\n getPreparedDatasetStatesIdentity(stableStates) !==\n getPreparedDatasetStatesIdentity(datasetStates)\n ) {\n setStableStates(datasetStates);\n }\n return stableStates;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export { DeckMapSettingsPanel, type DeckMapSettingsPanelProps, } from './MapSett
|
|
|
9
9
|
export { DeckMapBlockRenderer, ensureDeckMapResourceState, type DeckMapBlockRendererProps, } from './block';
|
|
10
10
|
export { asDeckJsonMapConfig, createEmptyDeckMapConfig, createDeckMapDashboardPanelConfig, DEFAULT_DECK_MAP_MAX_DATA_POINTS, DECK_MAP_DASHBOARD_PANEL_TYPE, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
|
|
11
11
|
export { getDeckMapDataPolicy, type DeckMapDataPolicy } from './mapDataPolicy';
|
|
12
|
-
export { createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
|
|
13
|
-
export type { DeckMapConfigColumn, DeckMapFillColor, DeckMapTableReference, } from './mapConfigUtils';
|
|
12
|
+
export { applyDeckMapPointBinding, createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
|
|
13
|
+
export type { DeckMapConfigColumn, DeckMapFillColor, DeckMapPointBinding, DeckMapTableReference, } from './mapConfigUtils';
|
|
14
14
|
export { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './datasetSourceUtils';
|
|
15
15
|
export type { DeckMapDatasetSourceConfig } from './datasetSourceUtils';
|
|
16
16
|
export { DeckMapResourceConfigParameter, DeckMapResourceToolParameters, } from './mapAiConfig';
|
|
@@ -23,7 +23,10 @@ export { DeckMapSurface, directDeckMapDataAdapter, type DeckMapDataAdapter, type
|
|
|
23
23
|
export { DECK_MAP_BLOCK_DEFAULT_HEIGHT, DECK_MAP_BLOCK_DEFAULT_TITLE, DECK_MAP_BLOCK_TYPE, createDeckMapBlockDocumentCommandType, createDeckMapBlockDocumentType, type DeckMapBlockDocumentRegistrationOptions, } from './blockDocumentRegistration';
|
|
24
24
|
export type { DeckMapConfigMode, DeckMapDashboardFitToDataConfig, CreateDeckMapDashboardPanelConfigOptions, DeckMapDashboardDatasetConfig, DeckMapDataPolicyOverride, DeckMapDashboardInteractionConfig, DeckMapDashboardPanelConfig, DeckMapConfig, DeckMapDatasetConfig, DeckMapDatasetSource, DeckMapFitToDataConfig, DeckMapInteractionConfig, } from './mapConfig';
|
|
25
25
|
export { DeckJsonMap } from './DeckJsonMap';
|
|
26
|
-
export {
|
|
26
|
+
export { DECK_MAP_BASEMAP_STYLES, getDefaultDeckMapStyle } from './mapStyles';
|
|
27
|
+
export { createProtomapsBasemapProvider, createProtomapsDefaultStyles, createProtomapsStyle, type ProtomapsFlavor, } from './protomapsStyles';
|
|
28
|
+
export { DeckMapDefaultStylesProvider, useDeckMapDefaultStyles, } from './DeckMapDefaultStylesProvider';
|
|
29
|
+
export { resolveDeckMapStyle, type DeckMapBasemapProvider, type DeckMapDefaultStyles, type DeckMapStyle, } from './basemap';
|
|
27
30
|
export { ColorScaleFunction, GeometryEncodingHint as DeckGeometryEncodingHint, DeckJsonMapLayerSpec, DeckJsonMapSpec, LayerBindingConfig, LayerBindingProps, } from './DeckJsonMapSpec';
|
|
28
31
|
export { createDeckJsonConfiguration } from './json/createDeckJsonConfiguration';
|
|
29
32
|
export { prepareDeckDataset } from './prepare/prepareDeckDataset';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,8BAA8B,EAAC,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,yBAAyB,GAC/B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,iCAAiC,EACjC,gCAAgC,EAChC,6BAA6B,EAC7B,kCAAkC,EAClC,oCAAoC,GACrC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,oBAAoB,EAAE,KAAK,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,oCAAoC,EACpC,2BAA2B,EAC3B,yCAAyC,EACzC,8BAA8B,EAC9B,mCAAmC,EACnC,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAC,0BAA0B,EAAC,MAAM,sBAAsB,CAAC;AACrE,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,8BAA8B,EAC9B,+BAA+B,EAC/B,KAAK,iCAAiC,EACtC,KAAK,0BAA0B,EAC/B,KAAK,sCAAsC,GAC5C,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,6BAA6B,EAC7B,KAAK,iCAAiC,EACtC,KAAK,mCAAmC,EACxC,KAAK,mCAAmC,GACzC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,8BAA8B,EAC9B,KAAK,uCAAuC,GAC7C,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,iBAAiB,EACjB,+BAA+B,EAC/B,wCAAwC,EACxC,6BAA6B,EAC7B,yBAAyB,EACzB,iCAAiC,EACjC,2BAA2B,EAC3B,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { DeckMapSettingsPanel, } from './MapSettings';
|
|
|
9
9
|
export { DeckMapBlockRenderer, ensureDeckMapResourceState, } from './block';
|
|
10
10
|
export { asDeckJsonMapConfig, createEmptyDeckMapConfig, createDeckMapDashboardPanelConfig, DEFAULT_DECK_MAP_MAX_DATA_POINTS, DECK_MAP_DASHBOARD_PANEL_TYPE, isDeckMapDashboardSqlDatasetSource, isDeckMapDashboardTableDatasetSource, } from './mapConfig';
|
|
11
11
|
export { getDeckMapDataPolicy } from './mapDataPolicy';
|
|
12
|
-
export { createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
|
|
12
|
+
export { applyDeckMapPointBinding, createDeckMapDashboardConfigForTable, createDeckMapConfigForTable, createDeckMapDashboardPanelConfigForTable, createDeckMapPointTransformSql, findDeckMapLongitudeLatitudeColumns, findGeometryColumn, findLongitudeLatitudeColumns, normalizeDeckMapFillColor, normalizeDeckMapPointConfig, quoteDeckMapSqlIdentifier, quoteDeckMapSqlTableReference, regenerateMapConfigForTable, } from './mapConfigUtils';
|
|
13
13
|
export { getFirstDatasetSourceTableName, hasSqlOnlyDatasetSource, } from './datasetSourceUtils';
|
|
14
14
|
export { DeckMapResourceConfigParameter, DeckMapResourceToolParameters, } from './mapAiConfig';
|
|
15
15
|
export { normalizeAiDeckMapConfig, prepareAiDeckMapConfig, validateAndFixColorScaleFields, } from './aiNormalize';
|
|
@@ -19,7 +19,10 @@ export { DeckMapResourceSchema, DeckMapsSliceConfig, createDeckMapsSlice, useSto
|
|
|
19
19
|
export { DeckMapSurface, directDeckMapDataAdapter, } from './DeckMapSurface';
|
|
20
20
|
export { DECK_MAP_BLOCK_DEFAULT_HEIGHT, DECK_MAP_BLOCK_DEFAULT_TITLE, DECK_MAP_BLOCK_TYPE, createDeckMapBlockDocumentCommandType, createDeckMapBlockDocumentType, } from './blockDocumentRegistration';
|
|
21
21
|
export { DeckJsonMap } from './DeckJsonMap';
|
|
22
|
-
export {
|
|
22
|
+
export { DECK_MAP_BASEMAP_STYLES, getDefaultDeckMapStyle } from './mapStyles';
|
|
23
|
+
export { createProtomapsBasemapProvider, createProtomapsDefaultStyles, createProtomapsStyle, } from './protomapsStyles';
|
|
24
|
+
export { DeckMapDefaultStylesProvider, useDeckMapDefaultStyles, } from './DeckMapDefaultStylesProvider';
|
|
25
|
+
export { resolveDeckMapStyle, } from './basemap';
|
|
23
26
|
export { ColorScaleFunction, GeometryEncodingHint as DeckGeometryEncodingHint, DeckJsonMapLayerSpec, DeckJsonMapSpec, LayerBindingConfig, LayerBindingProps, } from './DeckJsonMapSpec';
|
|
24
27
|
export { createDeckJsonConfiguration } from './json/createDeckJsonConfiguration';
|
|
25
28
|
export { prepareDeckDataset } from './prepare/prepareDeckDataset';
|