@honua/react 0.1.0-beta.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/contract/discovery.d.ts +231 -0
  2. package/contract/discovery.d.ts.map +1 -0
  3. package/contract/discovery.js +554 -0
  4. package/contract/edit-sketch.d.ts +8 -0
  5. package/contract/edit-sketch.d.ts.map +1 -1
  6. package/contract/edit-sketch.js +15 -0
  7. package/contract/edit-snapping.d.ts +160 -0
  8. package/contract/edit-snapping.d.ts.map +1 -0
  9. package/contract/edit-snapping.js +675 -0
  10. package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
  11. package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
  12. package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
  13. package/contract/index.d.ts +11 -2
  14. package/contract/index.d.ts.map +1 -1
  15. package/contract/index.js +4 -1
  16. package/contract/pmtiles.d.ts +31 -0
  17. package/contract/pmtiles.d.ts.map +1 -1
  18. package/contract/pmtiles.js +60 -20
  19. package/contract/protocol-module.d.ts +70 -0
  20. package/contract/protocol-module.d.ts.map +1 -0
  21. package/contract/protocol-module.js +1 -0
  22. package/contract/schema-envelope.d.ts +26 -0
  23. package/contract/schema-envelope.d.ts.map +1 -0
  24. package/contract/schema-envelope.js +25 -0
  25. package/contract/schema.d.ts +582 -0
  26. package/contract/schema.d.ts.map +1 -0
  27. package/contract/schema.js +2483 -0
  28. package/contract/source-capability-support.d.ts +6 -0
  29. package/contract/source-capability-support.d.ts.map +1 -0
  30. package/contract/source-capability-support.js +154 -0
  31. package/contract/source.d.ts +35 -17
  32. package/contract/source.d.ts.map +1 -1
  33. package/contract/source.js +267 -71
  34. package/contract/types.d.ts +140 -4
  35. package/contract/types.d.ts.map +1 -1
  36. package/contract/types.js +6 -14
  37. package/core/bounded-json.d.ts +4 -0
  38. package/core/bounded-json.d.ts.map +1 -0
  39. package/core/bounded-json.js +38 -0
  40. package/core/cache-state.d.ts +9 -0
  41. package/core/cache-state.d.ts.map +1 -1
  42. package/core/cache-state.js +10 -0
  43. package/core/capabilities-xml.d.ts +33 -0
  44. package/core/capabilities-xml.d.ts.map +1 -0
  45. package/core/capabilities-xml.js +331 -0
  46. package/core/client.d.ts +4 -1
  47. package/core/client.d.ts.map +1 -1
  48. package/core/client.js +115 -29
  49. package/core/error-classifications.d.ts +153 -0
  50. package/core/error-classifications.d.ts.map +1 -0
  51. package/core/error-classifications.js +140 -0
  52. package/core/error-code-registry.d.ts +158 -0
  53. package/core/error-code-registry.d.ts.map +1 -0
  54. package/core/error-code-registry.js +143 -0
  55. package/core/error-envelope.d.ts +68 -0
  56. package/core/error-envelope.d.ts.map +1 -0
  57. package/core/error-envelope.js +357 -0
  58. package/core/errors.d.ts +45 -29
  59. package/core/errors.d.ts.map +1 -1
  60. package/core/errors.js +97 -50
  61. package/core/geoparquet-sql.d.ts +30 -2
  62. package/core/geoparquet-sql.d.ts.map +1 -1
  63. package/core/geoparquet-sql.js +38 -3
  64. package/core/odata-key-path.d.ts +12 -0
  65. package/core/odata-key-path.d.ts.map +1 -0
  66. package/core/odata-key-path.js +28 -0
  67. package/core/odata-write-codec.d.ts +66 -0
  68. package/core/odata-write-codec.d.ts.map +1 -0
  69. package/core/odata-write-codec.js +1083 -0
  70. package/core/odata.d.ts +59 -7
  71. package/core/odata.d.ts.map +1 -1
  72. package/core/odata.js +431 -99
  73. package/core/ogc-features.d.ts.map +1 -1
  74. package/core/ogc-features.js +3 -0
  75. package/core/ogc-maps.d.ts +7 -0
  76. package/core/ogc-maps.d.ts.map +1 -1
  77. package/core/ogc-maps.js +46 -7
  78. package/core/ogc-processes.d.ts +2 -1
  79. package/core/ogc-processes.d.ts.map +1 -1
  80. package/core/ogc-processes.js +33 -5
  81. package/core/ogc-records.d.ts +9 -0
  82. package/core/ogc-records.d.ts.map +1 -1
  83. package/core/ogc-records.js +78 -29
  84. package/core/ogc-tiles.d.ts +10 -1
  85. package/core/ogc-tiles.d.ts.map +1 -1
  86. package/core/ogc-tiles.js +56 -17
  87. package/core/path-utils.d.ts +9 -0
  88. package/core/path-utils.d.ts.map +1 -1
  89. package/core/path-utils.js +19 -0
  90. package/core/protocol-transport.d.ts +1 -0
  91. package/core/protocol-transport.d.ts.map +1 -1
  92. package/core/request-pipeline.d.ts.map +1 -1
  93. package/core/request-pipeline.js +1 -1
  94. package/core/spatial-filter.d.ts +8 -4
  95. package/core/spatial-filter.d.ts.map +1 -1
  96. package/core/spatial-filter.js +206 -16
  97. package/core/stac-static.d.ts +6 -2
  98. package/core/stac-static.d.ts.map +1 -1
  99. package/core/stac-static.js +260 -69
  100. package/core/surfaces.d.ts.map +1 -1
  101. package/core/surfaces.js +69 -5
  102. package/core/types.d.ts +125 -7
  103. package/core/types.d.ts.map +1 -1
  104. package/core/wfs-capabilities.d.ts +2 -0
  105. package/core/wfs-capabilities.d.ts.map +1 -1
  106. package/core/wfs-capabilities.js +8 -1
  107. package/core/wfs.d.ts.map +1 -1
  108. package/core/wfs.js +10 -0
  109. package/core/wms-capabilities.d.ts +56 -84
  110. package/core/wms-capabilities.d.ts.map +1 -1
  111. package/core/wms-capabilities.js +212 -509
  112. package/core/wmts-capabilities.d.ts +62 -62
  113. package/core/wmts-capabilities.d.ts.map +1 -1
  114. package/core/wmts-capabilities.js +224 -371
  115. package/esri-compat/editor.d.ts +8 -0
  116. package/esri-compat/editor.d.ts.map +1 -1
  117. package/esri-compat/editor.js +13 -0
  118. package/esri-compat/feature-layer.d.ts +2 -0
  119. package/esri-compat/feature-layer.d.ts.map +1 -1
  120. package/esri-compat/feature-layer.js +1 -0
  121. package/esri-compat/layer-list.d.ts +11 -0
  122. package/esri-compat/layer-list.d.ts.map +1 -1
  123. package/esri-compat/layer-list.js +49 -0
  124. package/esri-compat/legend.d.ts +10 -0
  125. package/esri-compat/legend.d.ts.map +1 -1
  126. package/esri-compat/legend.js +27 -0
  127. package/esri-compat/portal.d.ts +197 -0
  128. package/esri-compat/portal.d.ts.map +1 -0
  129. package/esri-compat/portal.js +251 -0
  130. package/esri-compat/renderer-objects.d.ts +40 -0
  131. package/esri-compat/renderer-objects.d.ts.map +1 -0
  132. package/esri-compat/renderer-objects.js +62 -0
  133. package/esri-compat/sketch.d.ts +43 -0
  134. package/esri-compat/sketch.d.ts.map +1 -1
  135. package/esri-compat/sketch.js +46 -0
  136. package/esri-compat/snapping.d.ts +43 -0
  137. package/esri-compat/snapping.d.ts.map +1 -0
  138. package/esri-compat/snapping.js +45 -0
  139. package/esri-compat/url.d.ts.map +1 -1
  140. package/esri-compat/url.js +1 -1
  141. package/esri-compat/widget-host.d.ts +84 -0
  142. package/esri-compat/widget-host.d.ts.map +1 -0
  143. package/esri-compat/widget-host.js +159 -0
  144. package/filter-registry/index.d.ts +145 -0
  145. package/filter-registry/index.d.ts.map +1 -0
  146. package/filter-registry/index.js +531 -0
  147. package/generated-app/errors.d.ts +18 -2
  148. package/generated-app/errors.d.ts.map +1 -1
  149. package/generated-app/errors.js +44 -11
  150. package/map/automatic-mount-integration.d.ts +134 -0
  151. package/map/automatic-mount-integration.d.ts.map +1 -0
  152. package/map/automatic-mount-integration.js +305 -0
  153. package/map/automatic-source-strategy.d.ts +125 -0
  154. package/map/automatic-source-strategy.d.ts.map +1 -0
  155. package/map/automatic-source-strategy.js +494 -0
  156. package/map/data-to-map-bridge.d.ts +293 -0
  157. package/map/data-to-map-bridge.d.ts.map +1 -0
  158. package/map/data-to-map-bridge.js +817 -0
  159. package/map/geojson-projection.d.ts +33 -0
  160. package/map/geojson-projection.d.ts.map +1 -0
  161. package/map/geojson-projection.js +118 -0
  162. package/map/index.d.ts +14 -0
  163. package/map/index.d.ts.map +1 -1
  164. package/map/index.js +8 -0
  165. package/map/raster-source-spec.d.ts +30 -0
  166. package/map/raster-source-spec.d.ts.map +1 -0
  167. package/map/raster-source-spec.js +190 -0
  168. package/map/raster-source-strategy.d.ts +65 -0
  169. package/map/raster-source-strategy.d.ts.map +1 -0
  170. package/map/raster-source-strategy.js +232 -0
  171. package/map/source-to-maplibre.d.ts +91 -0
  172. package/map/source-to-maplibre.d.ts.map +1 -0
  173. package/map/source-to-maplibre.js +454 -0
  174. package/map/temporal-playback.d.ts +139 -0
  175. package/map/temporal-playback.d.ts.map +1 -0
  176. package/map/temporal-playback.js +247 -0
  177. package/package.json +14 -1
  178. package/query-planner/canonical.d.ts +7 -0
  179. package/query-planner/canonical.d.ts.map +1 -0
  180. package/query-planner/canonical.js +145 -0
  181. package/query-planner/cql2-json.d.ts +17 -0
  182. package/query-planner/cql2-json.d.ts.map +1 -0
  183. package/query-planner/cql2-json.js +646 -0
  184. package/query-planner/diagnostics.d.ts +35 -0
  185. package/query-planner/diagnostics.d.ts.map +1 -0
  186. package/query-planner/diagnostics.js +373 -0
  187. package/query-planner/duckdb.d.ts +79 -0
  188. package/query-planner/duckdb.d.ts.map +1 -0
  189. package/query-planner/duckdb.js +758 -0
  190. package/query-planner/execution-context.d.ts +5 -0
  191. package/query-planner/execution-context.d.ts.map +1 -0
  192. package/query-planner/execution-context.js +50 -0
  193. package/query-planner/executor.d.ts +5 -0
  194. package/query-planner/executor.d.ts.map +1 -0
  195. package/query-planner/executor.js +223 -0
  196. package/query-planner/geoservices.d.ts +91 -0
  197. package/query-planner/geoservices.d.ts.map +1 -0
  198. package/query-planner/geoservices.js +667 -0
  199. package/query-planner/grpc.d.ts +100 -0
  200. package/query-planner/grpc.d.ts.map +1 -0
  201. package/query-planner/grpc.js +736 -0
  202. package/query-planner/index.d.ts +44 -0
  203. package/query-planner/index.d.ts.map +1 -0
  204. package/query-planner/index.js +30 -0
  205. package/query-planner/ir.d.ts +20 -0
  206. package/query-planner/ir.d.ts.map +1 -0
  207. package/query-planner/ir.js +417 -0
  208. package/query-planner/local-aggregate.d.ts +5 -0
  209. package/query-planner/local-aggregate.d.ts.map +1 -0
  210. package/query-planner/local-aggregate.js +126 -0
  211. package/query-planner/odata.d.ts +48 -0
  212. package/query-planner/odata.d.ts.map +1 -0
  213. package/query-planner/odata.js +662 -0
  214. package/query-planner/ogc-compiler.d.ts +55 -0
  215. package/query-planner/ogc-compiler.d.ts.map +1 -0
  216. package/query-planner/ogc-compiler.js +480 -0
  217. package/query-planner/ogc-features.d.ts +53 -0
  218. package/query-planner/ogc-features.d.ts.map +1 -0
  219. package/query-planner/ogc-features.js +617 -0
  220. package/query-planner/planner.d.ts +17 -0
  221. package/query-planner/planner.d.ts.map +1 -0
  222. package/query-planner/planner.js +818 -0
  223. package/query-planner/resource.d.ts +94 -0
  224. package/query-planner/resource.d.ts.map +1 -0
  225. package/query-planner/resource.js +526 -0
  226. package/query-planner/semantic-canonical.d.ts +15 -0
  227. package/query-planner/semantic-canonical.d.ts.map +1 -0
  228. package/query-planner/semantic-canonical.js +62 -0
  229. package/query-planner/semantic-compat.d.ts +10 -0
  230. package/query-planner/semantic-compat.d.ts.map +1 -0
  231. package/query-planner/semantic-compat.js +35 -0
  232. package/query-planner/semantic-compiler.d.ts +64 -0
  233. package/query-planner/semantic-compiler.d.ts.map +1 -0
  234. package/query-planner/semantic-compiler.js +81 -0
  235. package/query-planner/semantic-literals.d.ts +30 -0
  236. package/query-planner/semantic-literals.d.ts.map +1 -0
  237. package/query-planner/semantic-literals.js +133 -0
  238. package/query-planner/semantic-types.d.ts +265 -0
  239. package/query-planner/semantic-types.d.ts.map +1 -0
  240. package/query-planner/semantic-types.js +1 -0
  241. package/query-planner/semantic.d.ts +54 -0
  242. package/query-planner/semantic.d.ts.map +1 -0
  243. package/query-planner/semantic.js +1421 -0
  244. package/query-planner/types.d.ts +560 -0
  245. package/query-planner/types.d.ts.map +1 -0
  246. package/query-planner/types.js +49 -0
  247. package/query-planner/wfs-semantic.d.ts +58 -0
  248. package/query-planner/wfs-semantic.d.ts.map +1 -0
  249. package/query-planner/wfs-semantic.js +547 -0
  250. package/query-planner/wfs.d.ts +6 -0
  251. package/query-planner/wfs.d.ts.map +1 -0
  252. package/query-planner/wfs.js +71 -0
  253. package/react/external-map.d.ts +67 -0
  254. package/react/external-map.d.ts.map +1 -0
  255. package/react/external-map.js +63 -0
  256. package/react/honua-map.d.ts.map +1 -1
  257. package/react/honua-map.js +3 -2
  258. package/react/honua-source-layer.d.ts +110 -0
  259. package/react/honua-source-layer.d.ts.map +1 -0
  260. package/react/honua-source-layer.js +101 -0
  261. package/react/hooks.d.ts +28 -0
  262. package/react/hooks.d.ts.map +1 -1
  263. package/react/hooks.js +26 -4
  264. package/react/index.d.ts +8 -0
  265. package/react/index.d.ts.map +1 -1
  266. package/react/index.js +5 -0
  267. package/react/query-cache.d.ts +26 -4
  268. package/react/query-cache.d.ts.map +1 -1
  269. package/react/query-cache.js +51 -8
  270. package/react/selection.d.ts +177 -0
  271. package/react/selection.d.ts.map +1 -0
  272. package/react/selection.js +0 -0
  273. package/react/use-mounted-source.d.ts +69 -0
  274. package/react/use-mounted-source.d.ts.map +1 -0
  275. package/react/use-mounted-source.js +346 -0
  276. package/runtime/edit-snapping.d.ts +107 -0
  277. package/runtime/edit-snapping.d.ts.map +1 -0
  278. package/runtime/edit-snapping.js +190 -0
  279. package/runtime/errors.d.ts +3 -2
  280. package/runtime/errors.d.ts.map +1 -1
  281. package/runtime/errors.js +19 -2
  282. package/runtime/index.d.ts +6 -0
  283. package/runtime/index.d.ts.map +1 -1
  284. package/runtime/index.js +3 -0
  285. package/runtime/maplibre-renderer.d.ts +41 -0
  286. package/runtime/maplibre-renderer.d.ts.map +1 -0
  287. package/runtime/maplibre-renderer.js +322 -0
  288. package/runtime/query-tiles.d.ts +2 -1
  289. package/runtime/query-tiles.d.ts.map +1 -1
  290. package/runtime/query-tiles.js +6 -2
  291. package/runtime/source-bridge.d.ts +4 -4
  292. package/runtime/source-bridge.d.ts.map +1 -1
  293. package/runtime/source-bridge.js +9 -56
  294. package/runtime/style-interactions.d.ts +3 -2
  295. package/runtime/style-interactions.d.ts.map +1 -1
  296. package/runtime/style-interactions.js +11 -3
  297. package/runtime/terra-draw-sketch.d.ts +275 -0
  298. package/runtime/terra-draw-sketch.d.ts.map +1 -0
  299. package/runtime/terra-draw-sketch.js +404 -0
  300. package/source-capability-registry.d.ts +1 -0
  301. package/source-capability-registry.js +1 -0
  302. package/source-capability-types.d.ts +186 -0
  303. package/source-capability-types.js +7 -0
  304. package/style/index.d.ts +2 -0
  305. package/style/index.d.ts.map +1 -1
  306. package/style/index.js +2 -0
  307. package/style/renderers.d.ts +326 -0
  308. package/style/renderers.d.ts.map +1 -0
  309. package/style/renderers.js +517 -0
  310. package/webmap/convert-renderer.d.ts +24 -3
  311. package/webmap/convert-renderer.d.ts.map +1 -1
  312. package/webmap/convert-renderer.js +93 -112
  313. package/webmap/index.d.ts +1 -1
  314. package/webmap/index.d.ts.map +1 -1
  315. package/webmap/index.js +1 -1
@@ -0,0 +1,531 @@
1
+ /**
2
+ * `@honua/sdk-js/filter-registry` — shared filter / crossfilter registry.
3
+ *
4
+ * Protocol-neutral state container for map, chart, table, search, and control
5
+ * filters. Projection helpers translate active clauses into existing SDK
6
+ * query, linked-view, widget, runtime-style, and URL state.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { createFilterRegistry, projectFilterRegistryToQuery } from "@honua/sdk-js/filter-registry";
11
+ *
12
+ * const registry = createFilterRegistry();
13
+ * registry.set("status", { field: "STATUS", op: "=", value: "ACTIVE" });
14
+ * registry.set("severity", { field: "SEVERITY", op: ">=", value: 3 });
15
+ *
16
+ * const query = projectFilterRegistryToQuery(registry, { sourceId: "incidents" });
17
+ * const { features } = await dataset.source("incidents")!.queryAll(query);
18
+ * ```
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ const SERVER_FILTER_PROTOCOLS = new Set([
23
+ "grpc",
24
+ "geoservices-feature-service",
25
+ "geoservices-map-service",
26
+ "ogc-features",
27
+ "wfs",
28
+ "odata",
29
+ ]);
30
+ const FILTER_OWNER_KINDS = new Set([
31
+ "map",
32
+ "chart",
33
+ "table",
34
+ "search",
35
+ "control",
36
+ "component",
37
+ ]);
38
+ const FILTER_LIFECYCLES = new Set(["persistent", "session", "transient"]);
39
+ const FILTER_EFFECTS = new Set(["filter", "crossfilter", "selection", "search", "spatial-mask"]);
40
+ const FILTER_OPERATORS = new Set([
41
+ "=",
42
+ "!=",
43
+ "<",
44
+ "<=",
45
+ ">",
46
+ ">=",
47
+ "in",
48
+ "not-in",
49
+ "between",
50
+ "like",
51
+ "is-null",
52
+ "is-not-null",
53
+ ]);
54
+ const FILTER_FIELD_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
55
+ /** Create an in-memory filter registry with owner-scoped mutation helpers. */
56
+ export function createFilterRegistry(options = {}) {
57
+ let clauses = normalizeClauses(options.initialClauses ?? []);
58
+ let snapshot = freezeSnapshot({ version: 1, clauses });
59
+ const listeners = new Set();
60
+ function publish(previous, changedIds) {
61
+ if (changedIds.size === 0)
62
+ return;
63
+ const event = { snapshot, previous, changedIds };
64
+ for (const listener of [...listeners])
65
+ listener(event);
66
+ }
67
+ function commit(nextClauses, changedIds) {
68
+ const previous = snapshot;
69
+ clauses = normalizeClauses(nextClauses);
70
+ snapshot = freezeSnapshot({ version: 1, clauses });
71
+ publish(previous, changedIds);
72
+ }
73
+ return {
74
+ get snapshot() {
75
+ return snapshot;
76
+ },
77
+ upsert(clause) {
78
+ const byId = new Map(clauses.map((entry) => [entry.id, entry]));
79
+ const existing = byId.get(clause.id);
80
+ if (existing && valuesEqual(existing, clause))
81
+ return;
82
+ byId.set(clause.id, normalizeClause(clause));
83
+ commit([...byId.values()], new Set([clause.id]));
84
+ },
85
+ remove(id) {
86
+ if (!clauses.some((clause) => clause.id === id))
87
+ return;
88
+ commit(clauses.filter((clause) => clause.id !== id), new Set([id]));
89
+ },
90
+ clearOwner(owner) {
91
+ const changed = clauses.filter((clause) => ownerKey(clause.owner) === ownerKey(owner)).map((clause) => clause.id);
92
+ if (changed.length === 0)
93
+ return;
94
+ commit(clauses.filter((clause) => ownerKey(clause.owner) !== ownerKey(owner)), new Set(changed));
95
+ },
96
+ clearSource(sourceId) {
97
+ const changed = clauses
98
+ .filter((clause) => appliesExplicitlyToSource(clause, sourceId))
99
+ .map((clause) => clause.id);
100
+ if (changed.length === 0)
101
+ return;
102
+ commit(clauses.filter((clause) => !appliesExplicitlyToSource(clause, sourceId)), new Set(changed));
103
+ },
104
+ setEnabled(id, enabled) {
105
+ let changed = false;
106
+ const next = clauses.map((clause) => {
107
+ if (clause.id !== id || (clause.enabled ?? true) === enabled)
108
+ return clause;
109
+ changed = true;
110
+ return { ...clause, enabled };
111
+ });
112
+ if (changed)
113
+ commit(next, new Set([id]));
114
+ },
115
+ replace(nextSnapshot) {
116
+ if (nextSnapshot.version !== 1)
117
+ throw new Error(`Unsupported filter registry snapshot version ${nextSnapshot.version}`);
118
+ const next = normalizeClauses(nextSnapshot.clauses);
119
+ if (valuesEqual(clauses, next))
120
+ return;
121
+ const ids = new Set([...clauses.map((clause) => clause.id), ...next.map((clause) => clause.id)]);
122
+ commit(next, ids);
123
+ },
124
+ subscribe(listener) {
125
+ listeners.add(listener);
126
+ return () => listeners.delete(listener);
127
+ },
128
+ select(selector, listener, options = {}) {
129
+ const equals = options.equals ?? valuesEqual;
130
+ let current = selector(snapshot);
131
+ if (options.fireImmediately)
132
+ listener(current, undefined);
133
+ return this.subscribe((event) => {
134
+ const next = selector(event.snapshot);
135
+ if (equals(current, next))
136
+ return;
137
+ current = next;
138
+ listener(next, event);
139
+ });
140
+ },
141
+ };
142
+ }
143
+ /** Return active clauses in deterministic id order, optionally source-scoped. */
144
+ export function selectActiveFilterClauses(snapshot, options = {}) {
145
+ return snapshot.clauses
146
+ .filter(isFilterClause)
147
+ .filter((clause) => (options.includeDisabled || (clause.enabled ?? true)) && appliesToSource(clause, options.sourceId))
148
+ .sort(compareClause);
149
+ }
150
+ /** Project active registry clauses into query/widget/linked-view/runtime state. */
151
+ export function projectFilterRegistryToQuery(snapshot, options = {}) {
152
+ const active = selectActiveFilterClauses(snapshot, options);
153
+ const filters = toProjectionFilters(active);
154
+ const linkedViewFilters = toLinkedViewFilters(active);
155
+ const where = compileWhere(active);
156
+ const spatialFilter = firstSpatialFilter(active);
157
+ const query = {
158
+ ...(options.baseQuery ?? {}),
159
+ ...(combineWhere(options.baseQuery?.where, where) ? { where: combineWhere(options.baseQuery?.where, where) } : {}),
160
+ ...((options.baseQuery?.spatialFilter ?? spatialFilter)
161
+ ? { spatialFilter: options.baseQuery?.spatialFilter ?? spatialFilter }
162
+ : {}),
163
+ };
164
+ const projection = {
165
+ filters,
166
+ ...(spatialFilter ? { spatialFilter } : {}),
167
+ };
168
+ const linkedView = {
169
+ filters: linkedViewFilters,
170
+ ...(spatialFilter ? { spatialFilter } : {}),
171
+ orderBy: (query.orderBy ?? []),
172
+ pagination: (query.pagination ?? {}),
173
+ ...(query.outFields ? { outFields: query.outFields } : {}),
174
+ grouping: [],
175
+ ...(query.aggregation ? { aggregation: query.aggregation } : {}),
176
+ selection: [],
177
+ };
178
+ const degraded = degradationFor(options.source, active);
179
+ return {
180
+ query,
181
+ ...(where ? { where } : {}),
182
+ projection,
183
+ linkedView,
184
+ runtimeFilter: compileRuntimeStyleFilter(active),
185
+ ...(degraded.length > 0 ? { degraded } : {}),
186
+ cacheKey: serializeFilterRegistry(snapshot, { sourceId: options.sourceId }),
187
+ cacheable: active.every((clause) => clause.cacheable !== false && clause.lifecycle !== "transient"),
188
+ };
189
+ }
190
+ /** Project active clauses directly into a `WidgetSourceProjection`. */
191
+ export function projectFilterRegistryToWidgetProjection(snapshot, options = {}) {
192
+ const projection = projectFilterRegistryToQuery(snapshot, options).projection;
193
+ return projection;
194
+ }
195
+ /** Project active clauses into the linked-view projection consumed by existing helpers. */
196
+ export function projectFilterRegistryToLinkedView(snapshot, options = {}) {
197
+ return projectFilterRegistryToQuery(snapshot, options).linkedView;
198
+ }
199
+ /** Compile active field clauses into a MapLibre-compatible expression tree. */
200
+ export function compileRuntimeStyleFilter(clauses) {
201
+ const parts = clauses
202
+ .filter((clause) => (clause.enabled ?? true) && clause.field && clause.operator)
203
+ .map(compileRuntimeClause)
204
+ .filter((entry) => entry !== undefined);
205
+ if (parts.length === 0)
206
+ return undefined;
207
+ return parts.length === 1 ? parts[0] : ["all", ...parts];
208
+ }
209
+ /** Deterministic URL/cache serialization. Secret or large values are omitted. */
210
+ export function serializeFilterRegistry(snapshot, options = {}) {
211
+ const shareable = {
212
+ version: 1,
213
+ clauses: selectActiveFilterClauses(snapshot, options)
214
+ .filter((clause) => clause.lifecycle !== "transient")
215
+ .map(shareableClause),
216
+ };
217
+ return stableShareStringify(shareable);
218
+ }
219
+ /** Parse a registry serialization produced by `serializeFilterRegistry`. */
220
+ export function parseFilterRegistry(value) {
221
+ if (!value)
222
+ return freezeSnapshot({ version: 1, clauses: [] });
223
+ try {
224
+ const parsed = JSON.parse(value);
225
+ if (parsed.version !== 1 || !Array.isArray(parsed.clauses))
226
+ return freezeSnapshot({ version: 1, clauses: [] });
227
+ return freezeSnapshot({ version: 1, clauses: normalizeClauses(parsed.clauses.filter(isFilterClause)) });
228
+ }
229
+ catch {
230
+ return freezeSnapshot({ version: 1, clauses: [] });
231
+ }
232
+ }
233
+ function toProjectionFilters(clauses) {
234
+ const out = {};
235
+ for (const clause of clauses) {
236
+ if (!clause.field || !clause.operator)
237
+ continue;
238
+ out[clause.id] = {
239
+ field: clause.field,
240
+ operator: clause.operator,
241
+ ...(clause.value !== undefined ? { value: clause.value } : {}),
242
+ ...(Array.isArray(clause.sourceScope) ? { appliesTo: clause.sourceScope } : {}),
243
+ };
244
+ }
245
+ return out;
246
+ }
247
+ function toLinkedViewFilters(clauses) {
248
+ const out = {};
249
+ for (const clause of clauses) {
250
+ if (!clause.field || !clause.operator)
251
+ continue;
252
+ out[clause.id] = {
253
+ field: clause.field,
254
+ operator: clause.operator,
255
+ ...(clause.value !== undefined ? { value: clause.value } : {}),
256
+ ...(Array.isArray(clause.sourceScope) ? { appliesTo: clause.sourceScope } : {}),
257
+ };
258
+ }
259
+ return out;
260
+ }
261
+ function compileWhere(clauses) {
262
+ const parts = clauses
263
+ .map(compileClauseWhere)
264
+ .filter((entry) => entry !== undefined)
265
+ .map((entry) => `(${entry})`);
266
+ return parts.length > 0 ? parts.join(" AND ") : undefined;
267
+ }
268
+ function compileClauseWhere(clause) {
269
+ if (!clause.field || !clause.operator)
270
+ return undefined;
271
+ const field = sqlIdentifier(clause.field);
272
+ if (!field)
273
+ return undefined;
274
+ switch (clause.operator) {
275
+ case "=":
276
+ return `${field} = ${literal(clause.value)}`;
277
+ case "!=":
278
+ return `${field} <> ${literal(clause.value)}`;
279
+ case "<":
280
+ case "<=":
281
+ case ">":
282
+ case ">=":
283
+ return `${field} ${clause.operator} ${literal(clause.value)}`;
284
+ case "in":
285
+ case "not-in":
286
+ if (!Array.isArray(clause.value) || clause.value.length === 0)
287
+ return undefined;
288
+ return `${field} ${clause.operator === "not-in" ? "NOT " : ""}IN (${clause.value.map(literal).join(", ")})`;
289
+ case "between":
290
+ if (!Array.isArray(clause.value) || clause.value.length < 2)
291
+ return undefined;
292
+ return `${field} BETWEEN ${literal(clause.value[0])} AND ${literal(clause.value[1])}`;
293
+ case "like":
294
+ return `${field} LIKE ${literal(clause.value)}`;
295
+ case "is-null":
296
+ return `${field} IS NULL`;
297
+ case "is-not-null":
298
+ return `${field} IS NOT NULL`;
299
+ }
300
+ }
301
+ function compileRuntimeClause(clause) {
302
+ if (!clause.field || !clause.operator)
303
+ return undefined;
304
+ const get = ["get", clause.field];
305
+ switch (clause.operator) {
306
+ case "=":
307
+ return ["==", get, clause.value];
308
+ case "!=":
309
+ return ["!=", get, clause.value];
310
+ case "<":
311
+ case "<=":
312
+ case ">":
313
+ case ">=":
314
+ return [clause.operator, get, clause.value];
315
+ case "in":
316
+ return Array.isArray(clause.value) ? ["in", get, ["literal", clause.value]] : undefined;
317
+ case "not-in":
318
+ return Array.isArray(clause.value) ? ["!", ["in", get, ["literal", clause.value]]] : undefined;
319
+ case "is-null":
320
+ return ["==", get, null];
321
+ case "is-not-null":
322
+ return ["!=", get, null];
323
+ case "between":
324
+ if (!Array.isArray(clause.value) || clause.value.length < 2)
325
+ return undefined;
326
+ return ["all", [">=", get, clause.value[0]], ["<=", get, clause.value[1]]];
327
+ case "like":
328
+ return undefined;
329
+ }
330
+ }
331
+ function degradationFor(source, clauses) {
332
+ if (!source || clauses.length === 0)
333
+ return [];
334
+ const fieldClauses = clauses.filter((clause) => clause.field && clause.operator);
335
+ if (fieldClauses.length === 0)
336
+ return [];
337
+ const canQuery = source.capabilities.has("query");
338
+ const canServerFilter = canQuery && (source.capabilities.has("sql") || SERVER_FILTER_PROTOCOLS.has(source.protocol));
339
+ if (canServerFilter)
340
+ return [];
341
+ return [
342
+ degradedReason("query", source, `Filter registry kept ${fieldClauses.length} field filter(s) for runtime/client evaluation because ${source.protocol} cannot apply them server-side.`),
343
+ ];
344
+ }
345
+ function degradedReason(capability, source, reason) {
346
+ return { capability, protocol: source.protocol, sourceId: source.id, reason };
347
+ }
348
+ function firstSpatialFilter(clauses) {
349
+ for (const clause of clauses) {
350
+ if (clause.spatialScope?.filter)
351
+ return clause.spatialScope.filter;
352
+ if (clause.spatialScope?.extent) {
353
+ const extent = clause.spatialScope.extent;
354
+ return {
355
+ geometryType: "esriGeometryEnvelope",
356
+ geometry: { ...extent },
357
+ spatialRel: "esriSpatialRelIntersects",
358
+ };
359
+ }
360
+ }
361
+ return undefined;
362
+ }
363
+ function appliesToSource(clause, sourceId) {
364
+ if (!sourceId)
365
+ return true;
366
+ if (!clause.sourceScope || clause.sourceScope === "all")
367
+ return true;
368
+ return clause.sourceScope.includes(sourceId);
369
+ }
370
+ function appliesExplicitlyToSource(clause, sourceId) {
371
+ return Array.isArray(clause.sourceScope) && clause.sourceScope.includes(sourceId);
372
+ }
373
+ function shareableClause(clause) {
374
+ const normalized = normalizeClause(clause);
375
+ if (normalized.value === undefined)
376
+ return normalized;
377
+ const maxBytes = normalized.valuePolicy?.maxSerializedBytes ?? 2048;
378
+ const encoded = stableStringify(normalized.value);
379
+ if (normalized.valuePolicy?.secret || encoded.length > maxBytes) {
380
+ const { value: _value, ...withoutValue } = normalized;
381
+ return withoutValue;
382
+ }
383
+ return normalized;
384
+ }
385
+ function normalizeClauses(input) {
386
+ const byId = new Map();
387
+ for (const clause of input)
388
+ byId.set(clause.id, normalizeClause(clause));
389
+ return deepFreeze([...byId.values()].sort(compareClause));
390
+ }
391
+ function normalizeClause(clause) {
392
+ if (!isFilterClause(clause))
393
+ throw new Error("Invalid filter registry clause");
394
+ return deepFreeze({
395
+ id: clause.id,
396
+ owner: { kind: clause.owner.kind, id: clause.owner.id },
397
+ ...(clause.field !== undefined ? { field: clause.field } : {}),
398
+ ...(clause.operator !== undefined ? { operator: clause.operator } : {}),
399
+ ...(clause.value !== undefined ? { value: cloneJsonLike(clause.value) } : {}),
400
+ ...(clause.spatialScope !== undefined ? { spatialScope: cloneJsonLike(clause.spatialScope) } : {}),
401
+ enabled: clause.enabled ?? true,
402
+ lifecycle: clause.lifecycle ?? "session",
403
+ effect: clause.effect ?? (clause.spatialScope ? "spatial-mask" : "filter"),
404
+ sourceScope: cloneSourceScope(clause.sourceScope ?? "all"),
405
+ ...(clause.cacheable !== undefined ? { cacheable: clause.cacheable } : {}),
406
+ ...(clause.valuePolicy !== undefined ? { valuePolicy: cloneJsonLike(clause.valuePolicy) } : {}),
407
+ });
408
+ }
409
+ function compareClause(left, right) {
410
+ return left.id.localeCompare(right.id);
411
+ }
412
+ function ownerKey(owner) {
413
+ return `${owner.kind}:${owner.id}`;
414
+ }
415
+ function literal(value) {
416
+ if (value === null || value === undefined)
417
+ return "NULL";
418
+ if (typeof value === "number" || typeof value === "bigint")
419
+ return String(value);
420
+ if (typeof value === "boolean")
421
+ return value ? "TRUE" : "FALSE";
422
+ return `'${String(value).replace(/'/g, "''")}'`;
423
+ }
424
+ function sqlIdentifier(field) {
425
+ return FILTER_FIELD_IDENTIFIER.test(field) ? field : undefined;
426
+ }
427
+ function combineWhere(left, right) {
428
+ if (left && right)
429
+ return `(${left}) AND (${right})`;
430
+ return left || right || undefined;
431
+ }
432
+ function stableStringify(value) {
433
+ return JSON.stringify(sortJsonValue(value, false));
434
+ }
435
+ function stableShareStringify(value) {
436
+ return JSON.stringify(sortJsonValue(value, true));
437
+ }
438
+ function sortJsonValue(value, stripValuePolicy) {
439
+ if (Array.isArray(value))
440
+ return value.map((entry) => sortJsonValue(entry, stripValuePolicy));
441
+ if (!value || typeof value !== "object")
442
+ return value;
443
+ const out = {};
444
+ for (const key of Object.keys(value).sort()) {
445
+ if (stripValuePolicy && key === "valuePolicy")
446
+ continue;
447
+ out[key] = sortJsonValue(value[key], stripValuePolicy);
448
+ }
449
+ return out;
450
+ }
451
+ function valuesEqual(left, right) {
452
+ return stableStringify(left) === stableStringify(right);
453
+ }
454
+ function isFilterClause(value) {
455
+ if (!isRecord(value))
456
+ return false;
457
+ const record = value;
458
+ return (typeof record.id === "string" &&
459
+ record.id.length > 0 &&
460
+ isFilterRegistryOwner(record.owner) &&
461
+ validOptional(record.field, (field) => typeof field === "string" && FILTER_FIELD_IDENTIFIER.test(field)) &&
462
+ validOptional(record.operator, (operator) => typeof operator === "string" && FILTER_OPERATORS.has(operator)) &&
463
+ validOptional(record.sourceScope, isFilterSourceScope) &&
464
+ validOptional(record.lifecycle, (lifecycle) => typeof lifecycle === "string" && FILTER_LIFECYCLES.has(lifecycle)) &&
465
+ validOptional(record.effect, (effect) => typeof effect === "string" && FILTER_EFFECTS.has(effect)) &&
466
+ validOptional(record.enabled, (enabled) => typeof enabled === "boolean") &&
467
+ validOptional(record.cacheable, (cacheable) => typeof cacheable === "boolean") &&
468
+ validOptional(record.spatialScope, isRecord) &&
469
+ validOptional(record.valuePolicy, isFilterValuePolicy));
470
+ }
471
+ function isFilterRegistryOwner(value) {
472
+ if (!isRecord(value))
473
+ return false;
474
+ return (typeof value.kind === "string" &&
475
+ FILTER_OWNER_KINDS.has(value.kind) &&
476
+ typeof value.id === "string" &&
477
+ value.id.length > 0);
478
+ }
479
+ function isFilterSourceScope(value) {
480
+ return (value === "all" || (Array.isArray(value) && value.every((entry) => typeof entry === "string" && entry.length > 0)));
481
+ }
482
+ function isFilterValuePolicy(value) {
483
+ if (!isRecord(value))
484
+ return false;
485
+ return (validOptional(value.secret, (secret) => typeof secret === "boolean") &&
486
+ validOptional(value.maxSerializedBytes, (maxSerializedBytes) => typeof maxSerializedBytes === "number" && Number.isFinite(maxSerializedBytes)));
487
+ }
488
+ function validOptional(value, validate) {
489
+ return value === undefined || validate(value);
490
+ }
491
+ function cloneSourceScope(sourceScope) {
492
+ return Array.isArray(sourceScope) ? deepFreeze([...sourceScope]) : sourceScope;
493
+ }
494
+ function freezeSnapshot(snapshot) {
495
+ return deepFreeze(snapshot);
496
+ }
497
+ function cloneJsonLike(value) {
498
+ if (Array.isArray(value))
499
+ return value.map(cloneJsonLike);
500
+ if (value instanceof Date)
501
+ return new Date(value.getTime());
502
+ if (isPlainRecord(value)) {
503
+ const out = {};
504
+ for (const key of Object.keys(value))
505
+ out[key] = cloneJsonLike(value[key]);
506
+ return out;
507
+ }
508
+ return value;
509
+ }
510
+ function deepFreeze(value) {
511
+ if (!value || typeof value !== "object" || Object.isFrozen(value))
512
+ return value;
513
+ if (Array.isArray(value)) {
514
+ for (const entry of value)
515
+ deepFreeze(entry);
516
+ }
517
+ else {
518
+ for (const key of Object.keys(value))
519
+ deepFreeze(value[key]);
520
+ }
521
+ return Object.freeze(value);
522
+ }
523
+ function isRecord(value) {
524
+ return typeof value === "object" && value !== null && !Array.isArray(value);
525
+ }
526
+ function isPlainRecord(value) {
527
+ if (!isRecord(value))
528
+ return false;
529
+ const prototype = Object.getPrototypeOf(value);
530
+ return prototype === Object.prototype || prototype === null;
531
+ }
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @module
8
8
  */
9
+ import { HonuaSdkError } from "../core/error-envelope.js";
9
10
  export type HonuaGeneratedAppErrorCode = "unsupported-profile" | "unsupported-widget" | "missing-manifest" | "missing-manifest-artifact" | "missing-map-package" | "map-package-mismatch" | "missing-widget" | "missing-binding" | "map-load-failed" | "data-load-failed" | "render-failed" | "disposed";
10
11
  export type HonuaGeneratedAppErrorStage = "manifest" | "projection" | "load" | "interaction" | "render" | "dispose";
11
12
  export interface HonuaGeneratedAppErrorDetail {
@@ -25,7 +26,23 @@ export interface HonuaGeneratedAppDiagnostic {
25
26
  readonly message: string;
26
27
  readonly detail?: HonuaGeneratedAppErrorDetail;
27
28
  }
28
- export declare class HonuaGeneratedAppError extends Error {
29
+ /**
30
+ * Tagged generated-app preview/runtime failure. Participates in the shared
31
+ * SDK error envelope (`isHonuaError`, `serializeHonuaError`) while
32
+ * preserving the legacy `.code`/`.stage`/`.detail`/`.cause` fields consumed
33
+ * by {@link toGeneratedAppDiagnostic}. `detail` is an open, caller-supplied
34
+ * bag (`expected`/`received`/etc.) and is deliberately kept local-only — it
35
+ * is never placed in the envelope's serialized `context`.
36
+ *
37
+ * The base `HonuaSdkError.toJSON()` (the redacted envelope projection) is
38
+ * inherited unchanged, so `JSON.stringify(error)` now returns the safe,
39
+ * sanitized `SerializedHonuaError` shape rather than the raw diagnostic
40
+ * (which could otherwise echo an unsanitized `detail`). Callers that need
41
+ * the legacy `{name, code, stage, message, detail}` diagnostic shape use
42
+ * {@link toGeneratedAppDiagnostic}, which reads the documented fields
43
+ * directly rather than relying on `toJSON()`.
44
+ */
45
+ export declare class HonuaGeneratedAppError extends HonuaSdkError {
29
46
  readonly code: HonuaGeneratedAppErrorCode;
30
47
  readonly stage: HonuaGeneratedAppErrorStage;
31
48
  readonly detail: HonuaGeneratedAppErrorDetail | undefined;
@@ -35,7 +52,6 @@ export declare class HonuaGeneratedAppError extends Error {
35
52
  readonly detail?: HonuaGeneratedAppErrorDetail;
36
53
  readonly cause?: unknown;
37
54
  });
38
- toJSON(): HonuaGeneratedAppDiagnostic;
39
55
  }
40
56
  export declare function toGeneratedAppDiagnostic(error: unknown): HonuaGeneratedAppDiagnostic;
41
57
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/generated-app/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,0BAA0B,GAClC,qBAAqB,GACrB,oBAAoB,GACpB,kBAAkB,GAClB,2BAA2B,GAC3B,qBAAqB,GACrB,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,MAAM,2BAA2B,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,SAAgB,IAAI,EAAE,0BAA0B,CAAC;IACjD,SAAgB,KAAK,EAAE,2BAA2B,CAAC;IACnD,SAAgB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjE,SAAyB,KAAK,EAAE,OAAO,CAAC;gBAGtC,IAAI,EAAE,0BAA0B,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;QAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;QAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;KAC1B;IAUI,MAAM,IAAI,2BAA2B;CAS7C;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,2BAA2B,CAQpF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/generated-app/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAuB,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/E,MAAM,MAAM,0BAA0B,GAClC,qBAAqB,GACrB,oBAAoB,GACpB,kBAAkB,GAClB,2BAA2B,GAC3B,qBAAqB,GACrB,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,MAAM,2BAA2B,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAqBD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAuB,SAAQ,aAAa;IACvD,SAAgB,IAAI,EAAE,0BAA0B,CAAC;IACjD,SAAgB,KAAK,EAAE,2BAA2B,CAAC;IACnD,SAAgB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjE,SAAyB,KAAK,EAAE,OAAO,CAAC;gBAGtC,IAAI,EAAE,0BAA0B,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;QAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,4BAA4B,CAAC;QAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;KAC1B;CASJ;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,2BAA2B,CAgBpF"}
@@ -6,32 +6,65 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- export class HonuaGeneratedAppError extends Error {
9
+ import { HonuaSdkError } from "../core/error-envelope.js";
10
+ /**
11
+ * Legacy detailed reason codes mapped to registered `app.*` `sdkCode`
12
+ * values, one-to-one.
13
+ */
14
+ const GENERATED_APP_ERROR_SDK_CODES = {
15
+ "unsupported-profile": "app.unsupported-profile",
16
+ "unsupported-widget": "app.unsupported-widget",
17
+ "missing-manifest": "app.missing-manifest",
18
+ "missing-manifest-artifact": "app.missing-manifest-artifact",
19
+ "missing-map-package": "app.missing-map-package",
20
+ "map-package-mismatch": "app.map-package-mismatch",
21
+ "missing-widget": "app.missing-widget",
22
+ "missing-binding": "app.missing-binding",
23
+ "map-load-failed": "app.map-load-failed",
24
+ "data-load-failed": "app.data-load-failed",
25
+ "render-failed": "app.render-failed",
26
+ disposed: "app.disposed",
27
+ };
28
+ /**
29
+ * Tagged generated-app preview/runtime failure. Participates in the shared
30
+ * SDK error envelope (`isHonuaError`, `serializeHonuaError`) while
31
+ * preserving the legacy `.code`/`.stage`/`.detail`/`.cause` fields consumed
32
+ * by {@link toGeneratedAppDiagnostic}. `detail` is an open, caller-supplied
33
+ * bag (`expected`/`received`/etc.) and is deliberately kept local-only — it
34
+ * is never placed in the envelope's serialized `context`.
35
+ *
36
+ * The base `HonuaSdkError.toJSON()` (the redacted envelope projection) is
37
+ * inherited unchanged, so `JSON.stringify(error)` now returns the safe,
38
+ * sanitized `SerializedHonuaError` shape rather than the raw diagnostic
39
+ * (which could otherwise echo an unsanitized `detail`). Callers that need
40
+ * the legacy `{name, code, stage, message, detail}` diagnostic shape use
41
+ * {@link toGeneratedAppDiagnostic}, which reads the documented fields
42
+ * directly rather than relying on `toJSON()`.
43
+ */
44
+ export class HonuaGeneratedAppError extends HonuaSdkError {
10
45
  code;
11
46
  stage;
12
47
  detail;
13
48
  cause;
14
49
  constructor(code, message, options) {
15
- super(message);
50
+ super(GENERATED_APP_ERROR_SDK_CODES[code], message, options.cause === undefined ? {} : { cause: options.cause });
16
51
  this.name = "HonuaGeneratedAppError";
17
52
  this.code = code;
18
53
  this.stage = options.stage;
19
54
  this.detail = options.detail;
20
55
  this.cause = options.cause;
21
56
  }
22
- toJSON() {
57
+ }
58
+ export function toGeneratedAppDiagnostic(error) {
59
+ if (error instanceof HonuaGeneratedAppError) {
23
60
  return {
24
61
  name: "HonuaGeneratedAppError",
25
- code: this.code,
26
- stage: this.stage,
27
- message: this.message,
28
- ...(this.detail ? { detail: this.detail } : {}),
62
+ code: error.code,
63
+ stage: error.stage,
64
+ message: error.message,
65
+ ...(error.detail ? { detail: error.detail } : {}),
29
66
  };
30
67
  }
31
- }
32
- export function toGeneratedAppDiagnostic(error) {
33
- if (error instanceof HonuaGeneratedAppError)
34
- return error.toJSON();
35
68
  return {
36
69
  name: "HonuaGeneratedAppError",
37
70
  code: "render-failed",