@honua/sdk-esri-compat 0.0.6-alpha.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 (289) hide show
  1. package/README.md +5 -0
  2. package/contract/edit-session.d.ts +203 -0
  3. package/contract/edit-session.d.ts.map +1 -0
  4. package/contract/edit-session.js +717 -0
  5. package/contract/index.d.ts +20 -0
  6. package/contract/index.d.ts.map +1 -0
  7. package/contract/index.js +15 -0
  8. package/contract/jobs.d.ts +115 -0
  9. package/contract/jobs.d.ts.map +1 -0
  10. package/contract/jobs.js +22 -0
  11. package/contract/source.d.ts +138 -0
  12. package/contract/source.d.ts.map +1 -0
  13. package/contract/source.js +3364 -0
  14. package/contract/spatial-aggregation.d.ts +312 -0
  15. package/contract/spatial-aggregation.d.ts.map +1 -0
  16. package/contract/spatial-aggregation.js +196 -0
  17. package/contract/types.d.ts +542 -0
  18. package/contract/types.d.ts.map +1 -0
  19. package/contract/types.js +171 -0
  20. package/core/batch.d.ts +37 -0
  21. package/core/batch.d.ts.map +1 -0
  22. package/core/batch.js +78 -0
  23. package/core/cache-state.d.ts +76 -0
  24. package/core/cache-state.d.ts.map +1 -0
  25. package/core/cache-state.js +84 -0
  26. package/core/client.d.ts +289 -0
  27. package/core/client.d.ts.map +1 -0
  28. package/core/client.js +2625 -0
  29. package/core/errors.d.ts +68 -0
  30. package/core/errors.d.ts.map +1 -0
  31. package/core/errors.js +116 -0
  32. package/core/grpc-adapter.d.ts +23 -0
  33. package/core/grpc-adapter.d.ts.map +1 -0
  34. package/core/grpc-adapter.js +704 -0
  35. package/core/odata.d.ts +347 -0
  36. package/core/odata.d.ts.map +1 -0
  37. package/core/odata.js +837 -0
  38. package/core/ogc-conformance.d.ts +35 -0
  39. package/core/ogc-conformance.d.ts.map +1 -0
  40. package/core/ogc-conformance.js +121 -0
  41. package/core/ogc-maps.d.ts +45 -0
  42. package/core/ogc-maps.d.ts.map +1 -0
  43. package/core/ogc-maps.js +53 -0
  44. package/core/ogc-processes.d.ts +92 -0
  45. package/core/ogc-processes.d.ts.map +1 -0
  46. package/core/ogc-processes.js +325 -0
  47. package/core/ogc-tiles.d.ts +55 -0
  48. package/core/ogc-tiles.d.ts.map +1 -0
  49. package/core/ogc-tiles.js +81 -0
  50. package/core/pbf-decoder.d.ts +28 -0
  51. package/core/pbf-decoder.d.ts.map +1 -0
  52. package/core/pbf-decoder.js +627 -0
  53. package/core/query-builder.d.ts +261 -0
  54. package/core/query-builder.d.ts.map +1 -0
  55. package/core/query-builder.js +538 -0
  56. package/core/spatial-filter.d.ts +93 -0
  57. package/core/spatial-filter.d.ts.map +1 -0
  58. package/core/spatial-filter.js +153 -0
  59. package/core/stac.d.ts +43 -0
  60. package/core/stac.d.ts.map +1 -0
  61. package/core/stac.js +116 -0
  62. package/core/surfaces.d.ts +464 -0
  63. package/core/surfaces.d.ts.map +1 -0
  64. package/core/surfaces.js +1322 -0
  65. package/core/types.d.ts +1238 -0
  66. package/core/types.d.ts.map +1 -0
  67. package/core/types.js +13 -0
  68. package/core/wfs-capabilities.d.ts +143 -0
  69. package/core/wfs-capabilities.d.ts.map +1 -0
  70. package/core/wfs-capabilities.js +478 -0
  71. package/core/wfs-filter.d.ts +118 -0
  72. package/core/wfs-filter.d.ts.map +1 -0
  73. package/core/wfs-filter.js +586 -0
  74. package/core/wfs.d.ts +219 -0
  75. package/core/wfs.d.ts.map +1 -0
  76. package/core/wfs.js +406 -0
  77. package/core/wms-capabilities.d.ts +110 -0
  78. package/core/wms-capabilities.d.ts.map +1 -0
  79. package/core/wms-capabilities.js +566 -0
  80. package/core/wms-types.d.ts +128 -0
  81. package/core/wms-types.d.ts.map +1 -0
  82. package/core/wms-types.js +32 -0
  83. package/core/wms.d.ts +108 -0
  84. package/core/wms.d.ts.map +1 -0
  85. package/core/wms.js +182 -0
  86. package/core/wmts-capabilities.d.ts +82 -0
  87. package/core/wmts-capabilities.d.ts.map +1 -0
  88. package/core/wmts-capabilities.js +409 -0
  89. package/core/wmts.d.ts +80 -0
  90. package/core/wmts.d.ts.map +1 -0
  91. package/core/wmts.js +173 -0
  92. package/esri-compat/basemap-gallery.d.ts +38 -0
  93. package/esri-compat/basemap-gallery.d.ts.map +1 -0
  94. package/esri-compat/basemap-gallery.js +159 -0
  95. package/esri-compat/basemap-layer-list.d.ts +35 -0
  96. package/esri-compat/basemap-layer-list.d.ts.map +1 -0
  97. package/esri-compat/basemap-layer-list.js +139 -0
  98. package/esri-compat/basemap.d.ts +32 -0
  99. package/esri-compat/basemap.d.ts.map +1 -0
  100. package/esri-compat/basemap.js +84 -0
  101. package/esri-compat/bookmarks.d.ts +36 -0
  102. package/esri-compat/bookmarks.d.ts.map +1 -0
  103. package/esri-compat/bookmarks.js +108 -0
  104. package/esri-compat/class-breaks-renderer.d.ts +50 -0
  105. package/esri-compat/class-breaks-renderer.d.ts.map +1 -0
  106. package/esri-compat/class-breaks-renderer.js +164 -0
  107. package/esri-compat/color.d.ts +22 -0
  108. package/esri-compat/color.d.ts.map +1 -0
  109. package/esri-compat/color.js +106 -0
  110. package/esri-compat/controls.d.ts +174 -0
  111. package/esri-compat/controls.d.ts.map +1 -0
  112. package/esri-compat/controls.js +479 -0
  113. package/esri-compat/coordinate-conversion.d.ts +41 -0
  114. package/esri-compat/coordinate-conversion.d.ts.map +1 -0
  115. package/esri-compat/coordinate-conversion.js +125 -0
  116. package/esri-compat/directions.d.ts +45 -0
  117. package/esri-compat/directions.d.ts.map +1 -0
  118. package/esri-compat/directions.js +123 -0
  119. package/esri-compat/editor.d.ts +47 -0
  120. package/esri-compat/editor.d.ts.map +1 -0
  121. package/esri-compat/editor.js +170 -0
  122. package/esri-compat/esri-config.d.ts +16 -0
  123. package/esri-compat/esri-config.d.ts.map +1 -0
  124. package/esri-compat/esri-config.js +23 -0
  125. package/esri-compat/esri-request.d.ts +17 -0
  126. package/esri-compat/esri-request.d.ts.map +1 -0
  127. package/esri-compat/esri-request.js +66 -0
  128. package/esri-compat/event-bus.d.ts +106 -0
  129. package/esri-compat/event-bus.d.ts.map +1 -0
  130. package/esri-compat/event-bus.js +90 -0
  131. package/esri-compat/expand.d.ts +36 -0
  132. package/esri-compat/expand.d.ts.map +1 -0
  133. package/esri-compat/expand.js +97 -0
  134. package/esri-compat/extent.d.ts +43 -0
  135. package/esri-compat/extent.d.ts.map +1 -0
  136. package/esri-compat/extent.js +140 -0
  137. package/esri-compat/feature-form.d.ts +64 -0
  138. package/esri-compat/feature-form.d.ts.map +1 -0
  139. package/esri-compat/feature-form.js +137 -0
  140. package/esri-compat/feature-layer.d.ts +173 -0
  141. package/esri-compat/feature-layer.d.ts.map +1 -0
  142. package/esri-compat/feature-layer.js +655 -0
  143. package/esri-compat/feature-set.d.ts +32 -0
  144. package/esri-compat/feature-set.d.ts.map +1 -0
  145. package/esri-compat/feature-set.js +80 -0
  146. package/esri-compat/feature-table.d.ts +141 -0
  147. package/esri-compat/feature-table.d.ts.map +1 -0
  148. package/esri-compat/feature-table.js +500 -0
  149. package/esri-compat/feature-templates.d.ts +41 -0
  150. package/esri-compat/feature-templates.d.ts.map +1 -0
  151. package/esri-compat/feature-templates.js +97 -0
  152. package/esri-compat/feature.d.ts +33 -0
  153. package/esri-compat/feature.d.ts.map +1 -0
  154. package/esri-compat/feature.js +83 -0
  155. package/esri-compat/graphic.d.ts +46 -0
  156. package/esri-compat/graphic.d.ts.map +1 -0
  157. package/esri-compat/graphic.js +103 -0
  158. package/esri-compat/graphics-layer.d.ts +49 -0
  159. package/esri-compat/graphics-layer.d.ts.map +1 -0
  160. package/esri-compat/graphics-layer.js +185 -0
  161. package/esri-compat/group-layer.d.ts +48 -0
  162. package/esri-compat/group-layer.d.ts.map +1 -0
  163. package/esri-compat/group-layer.js +212 -0
  164. package/esri-compat/identify.d.ts +71 -0
  165. package/esri-compat/identify.d.ts.map +1 -0
  166. package/esri-compat/identify.js +299 -0
  167. package/esri-compat/identity-manager.d.ts +31 -0
  168. package/esri-compat/identity-manager.d.ts.map +1 -0
  169. package/esri-compat/identity-manager.js +115 -0
  170. package/esri-compat/label-class.d.ts +31 -0
  171. package/esri-compat/label-class.d.ts.map +1 -0
  172. package/esri-compat/label-class.js +102 -0
  173. package/esri-compat/layer-list.d.ts +77 -0
  174. package/esri-compat/layer-list.d.ts.map +1 -0
  175. package/esri-compat/layer-list.js +342 -0
  176. package/esri-compat/legend.d.ts +53 -0
  177. package/esri-compat/legend.d.ts.map +1 -0
  178. package/esri-compat/legend.js +254 -0
  179. package/esri-compat/map-image-layer.d.ts +162 -0
  180. package/esri-compat/map-image-layer.d.ts.map +1 -0
  181. package/esri-compat/map-image-layer.js +704 -0
  182. package/esri-compat/map-view.d.ts +315 -0
  183. package/esri-compat/map-view.d.ts.map +1 -0
  184. package/esri-compat/map-view.js +1110 -0
  185. package/esri-compat/map.d.ts +47 -0
  186. package/esri-compat/map.d.ts.map +1 -0
  187. package/esri-compat/map.js +209 -0
  188. package/esri-compat/measurement-2d.d.ts +61 -0
  189. package/esri-compat/measurement-2d.d.ts.map +1 -0
  190. package/esri-compat/measurement-2d.js +184 -0
  191. package/esri-compat/measurement.d.ts +45 -0
  192. package/esri-compat/measurement.d.ts.map +1 -0
  193. package/esri-compat/measurement.js +193 -0
  194. package/esri-compat/oauth-info.d.ts +35 -0
  195. package/esri-compat/oauth-info.d.ts.map +1 -0
  196. package/esri-compat/oauth-info.js +115 -0
  197. package/esri-compat/picture-marker-symbol.d.ts +35 -0
  198. package/esri-compat/picture-marker-symbol.d.ts.map +1 -0
  199. package/esri-compat/picture-marker-symbol.js +126 -0
  200. package/esri-compat/point.d.ts +31 -0
  201. package/esri-compat/point.d.ts.map +1 -0
  202. package/esri-compat/point.js +102 -0
  203. package/esri-compat/polygon.d.ts +31 -0
  204. package/esri-compat/polygon.d.ts.map +1 -0
  205. package/esri-compat/polygon.js +107 -0
  206. package/esri-compat/polyline.d.ts +31 -0
  207. package/esri-compat/polyline.d.ts.map +1 -0
  208. package/esri-compat/polyline.js +107 -0
  209. package/esri-compat/popup-template.d.ts +55 -0
  210. package/esri-compat/popup-template.d.ts.map +1 -0
  211. package/esri-compat/popup-template.js +128 -0
  212. package/esri-compat/popup.d.ts +54 -0
  213. package/esri-compat/popup.d.ts.map +1 -0
  214. package/esri-compat/popup.js +312 -0
  215. package/esri-compat/print.d.ts +47 -0
  216. package/esri-compat/print.d.ts.map +1 -0
  217. package/esri-compat/print.js +105 -0
  218. package/esri-compat/query.d.ts +46 -0
  219. package/esri-compat/query.d.ts.map +1 -0
  220. package/esri-compat/query.js +119 -0
  221. package/esri-compat/reactive-utils.d.ts +23 -0
  222. package/esri-compat/reactive-utils.d.ts.map +1 -0
  223. package/esri-compat/reactive-utils.js +178 -0
  224. package/esri-compat/request.d.ts +41 -0
  225. package/esri-compat/request.d.ts.map +1 -0
  226. package/esri-compat/request.js +253 -0
  227. package/esri-compat/route-layer.d.ts +59 -0
  228. package/esri-compat/route-layer.d.ts.map +1 -0
  229. package/esri-compat/route-layer.js +223 -0
  230. package/esri-compat/route-task.d.ts +88 -0
  231. package/esri-compat/route-task.d.ts.map +1 -0
  232. package/esri-compat/route-task.js +225 -0
  233. package/esri-compat/scene-view.d.ts +41 -0
  234. package/esri-compat/scene-view.d.ts.map +1 -0
  235. package/esri-compat/scene-view.js +68 -0
  236. package/esri-compat/search.d.ts +112 -0
  237. package/esri-compat/search.d.ts.map +1 -0
  238. package/esri-compat/search.js +820 -0
  239. package/esri-compat/simple-fill-symbol.d.ts +27 -0
  240. package/esri-compat/simple-fill-symbol.d.ts.map +1 -0
  241. package/esri-compat/simple-fill-symbol.js +85 -0
  242. package/esri-compat/simple-line-symbol.d.ts +27 -0
  243. package/esri-compat/simple-line-symbol.d.ts.map +1 -0
  244. package/esri-compat/simple-line-symbol.js +85 -0
  245. package/esri-compat/simple-marker-symbol.d.ts +29 -0
  246. package/esri-compat/simple-marker-symbol.d.ts.map +1 -0
  247. package/esri-compat/simple-marker-symbol.js +92 -0
  248. package/esri-compat/simple-renderer.d.ts +29 -0
  249. package/esri-compat/simple-renderer.d.ts.map +1 -0
  250. package/esri-compat/simple-renderer.js +92 -0
  251. package/esri-compat/sketch.d.ts +64 -0
  252. package/esri-compat/sketch.d.ts.map +1 -0
  253. package/esri-compat/sketch.js +227 -0
  254. package/esri-compat/spatial-reference.d.ts +31 -0
  255. package/esri-compat/spatial-reference.d.ts.map +1 -0
  256. package/esri-compat/spatial-reference.js +102 -0
  257. package/esri-compat/swipe.d.ts +34 -0
  258. package/esri-compat/swipe.d.ts.map +1 -0
  259. package/esri-compat/swipe.js +93 -0
  260. package/esri-compat/table-list.d.ts +36 -0
  261. package/esri-compat/table-list.d.ts.map +1 -0
  262. package/esri-compat/table-list.js +126 -0
  263. package/esri-compat/text-symbol.d.ts +37 -0
  264. package/esri-compat/text-symbol.d.ts.map +1 -0
  265. package/esri-compat/text-symbol.js +123 -0
  266. package/esri-compat/tile-layer.d.ts +52 -0
  267. package/esri-compat/tile-layer.d.ts.map +1 -0
  268. package/esri-compat/tile-layer.js +167 -0
  269. package/esri-compat/time-slider.d.ts +70 -0
  270. package/esri-compat/time-slider.d.ts.map +1 -0
  271. package/esri-compat/time-slider.js +208 -0
  272. package/esri-compat/track.d.ts +51 -0
  273. package/esri-compat/track.d.ts.map +1 -0
  274. package/esri-compat/track.js +174 -0
  275. package/esri-compat/unique-value-renderer.d.ts +41 -0
  276. package/esri-compat/unique-value-renderer.d.ts.map +1 -0
  277. package/esri-compat/unique-value-renderer.js +127 -0
  278. package/esri-compat/url.d.ts +12 -0
  279. package/esri-compat/url.d.ts.map +1 -0
  280. package/esri-compat/url.js +54 -0
  281. package/esri-compat/web-map.d.ts +14 -0
  282. package/esri-compat/web-map.d.ts.map +1 -0
  283. package/esri-compat/web-map.js +24 -0
  284. package/gen/honua/v1/feature_service_pb.d.ts +918 -0
  285. package/gen/honua/v1/feature_service_pb.d.ts.map +1 -0
  286. package/gen/honua/v1/feature_service_pb.js +375 -0
  287. package/index.d.ts +130 -0
  288. package/index.js +65 -0
  289. package/package.json +22 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Shared client contract — canonical nouns that all protocol adapters
3
+ * (`HonuaFeatureLayer`, `HonuaMapService`, `HonuaOgcFeatureCollection`, plus
4
+ * future WFS / WMS / OData adapters) must speak. The contract is documented
5
+ * in `docs/shared-client-contract.md`; capability coverage by protocol is
6
+ * documented in `docs/protocol-capability-matrix.md`.
7
+ *
8
+ * The runtime classes in `src/core/surfaces.ts` are not replaced — they
9
+ * remain the implementation. The contract here wraps their request /
10
+ * response shapes (`QueryFeaturesRequest`, `OgcItemsRequest`,
11
+ * `HonuaTypedQueryResponse`, `HonuaOgcFeatureCollectionResponse`) so that
12
+ * cross-protocol code can speak one vocabulary without re-litigating the
13
+ * surface in every downstream ticket.
14
+ *
15
+ * @module
16
+ */
17
+ /** All protocol identifiers, in declaration order. */
18
+ export const PROTOCOLS = [
19
+ "geoservices-feature-service",
20
+ "geoservices-map-service",
21
+ "geoservices-image-service",
22
+ "geoservices-geometry-service",
23
+ "geoservices-gp-service",
24
+ "ogc-features",
25
+ "ogc-tiles",
26
+ "ogc-maps",
27
+ "stac",
28
+ "wfs",
29
+ "wms",
30
+ "wmts",
31
+ "odata",
32
+ "maplibre-vector",
33
+ "maplibre-raster",
34
+ "maplibre-geojson",
35
+ ];
36
+ /** All capability identifiers, in declaration order. */
37
+ export const CAPABILITIES = [
38
+ "query",
39
+ "queryAggregate",
40
+ "spatialAggregate",
41
+ "queryExtent",
42
+ "queryObjectIds",
43
+ "queryRelated",
44
+ "applyEdits",
45
+ "attachments",
46
+ "render",
47
+ "tiles",
48
+ "sql",
49
+ "stream",
50
+ "pbf",
51
+ "connect",
52
+ "image",
53
+ "geometry",
54
+ "geoprocess",
55
+ "processes",
56
+ ];
57
+ /**
58
+ * Build a `Capabilities` set from a readonly array. Provided as a tiny
59
+ * helper so callers do not need to import `Set` literals at every adapter
60
+ * site.
61
+ */
62
+ export function capabilities(values) {
63
+ return new Set(values);
64
+ }
65
+ /**
66
+ * Compute the **weakest** (intersected) capability set across one or
67
+ * more participating sources / descriptors. This is the canonical helper
68
+ * for cross-protocol capability negotiation in a mixed-source
69
+ * composition (`#22`): a composition supports a capability only when
70
+ * **every** participating source supports it.
71
+ *
72
+ * Promising a capability the weakest source lacks is the worst possible
73
+ * mixed-source failure mode (silent wrong result), so consumers should
74
+ * always intersect before fanning a query out to a heterogeneous set.
75
+ *
76
+ * Accepts anything with a `capabilities` field (live `Source` instances
77
+ * or plain `SourceDescriptor`s). Empty input returns an empty set.
78
+ *
79
+ * For per-operation reasoning across a heterogeneous mix, partition
80
+ * sources first (e.g., feature sources only) and intersect on the
81
+ * partition; intersecting a render-only source with a feature source
82
+ * yields the empty set, which is honest but rarely actionable on its
83
+ * own.
84
+ */
85
+ export function intersectCapabilities(participants) {
86
+ if (participants.length === 0)
87
+ return new Set();
88
+ const [first, ...rest] = participants;
89
+ const out = new Set(first.capabilities);
90
+ for (const next of rest) {
91
+ for (const cap of out) {
92
+ if (!next.capabilities.has(cap))
93
+ out.delete(cap);
94
+ }
95
+ if (out.size === 0)
96
+ return out;
97
+ }
98
+ return out;
99
+ }
100
+ /**
101
+ * Companion of {@link intersectCapabilities}: the union (best-case)
102
+ * capability set across participants. Useful for documenting what
103
+ * capability fan-out under `degraded` policy could reach if every
104
+ * source were queried independently — never use this to gate a single
105
+ * fan-out call (that needs the intersection).
106
+ */
107
+ export function unionCapabilities(participants) {
108
+ const out = new Set();
109
+ for (const participant of participants) {
110
+ for (const cap of participant.capabilities)
111
+ out.add(cap);
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * Default capability sets keyed by protocol. Callers that need a narrower
117
+ * surface for a specific source must intersect the default set themselves
118
+ * and pass the result on `SourceDescriptor.capabilities`; the built-in
119
+ * adapter constructors do not read service metadata today.
120
+ *
121
+ * The matrix here mirrors the one in `docs/protocol-capability-matrix.md`.
122
+ * Update both together.
123
+ */
124
+ export const PROTOCOL_DEFAULT_CAPABILITIES = {
125
+ "geoservices-feature-service": capabilities([
126
+ "query",
127
+ "queryAggregate",
128
+ "queryExtent",
129
+ "queryObjectIds",
130
+ "queryRelated",
131
+ "applyEdits",
132
+ "attachments",
133
+ "sql",
134
+ "stream",
135
+ "pbf",
136
+ "connect",
137
+ ]),
138
+ "geoservices-map-service": capabilities([
139
+ "query",
140
+ "queryAggregate",
141
+ "queryExtent",
142
+ "queryObjectIds",
143
+ "queryRelated",
144
+ "render",
145
+ "tiles",
146
+ "sql",
147
+ "stream",
148
+ ]),
149
+ "geoservices-image-service": capabilities([
150
+ "query",
151
+ "queryExtent",
152
+ "queryObjectIds",
153
+ "image",
154
+ "render",
155
+ "tiles",
156
+ "connect",
157
+ ]),
158
+ "geoservices-geometry-service": capabilities(["geometry", "connect"]),
159
+ "geoservices-gp-service": capabilities(["geoprocess", "connect"]),
160
+ "ogc-features": capabilities(["query", "queryObjectIds", "applyEdits", "stream"]),
161
+ "ogc-tiles": capabilities(["render", "tiles"]),
162
+ "ogc-maps": capabilities(["render"]),
163
+ stac: capabilities(["query", "queryObjectIds", "stream"]),
164
+ wfs: capabilities(["query", "queryExtent", "queryObjectIds", "applyEdits", "stream"]),
165
+ wms: capabilities(["render", "tiles", "query"]),
166
+ wmts: capabilities(["render", "tiles"]),
167
+ odata: capabilities(["query", "queryObjectIds", "stream", "applyEdits"]),
168
+ "maplibre-vector": capabilities(["render", "tiles"]),
169
+ "maplibre-raster": capabilities(["render", "tiles"]),
170
+ "maplibre-geojson": capabilities(["render"]),
171
+ };
@@ -0,0 +1,37 @@
1
+ import type { HonuaClient } from "./client.js";
2
+ import type { HonuaQueryResponse, MapLayerQueryRequest, QueryFeaturesRequest } from "./types.js";
3
+ /** A single query item in a batch. */
4
+ export interface BatchQueryItem {
5
+ /** When `"map-layer"`, calls `client.queryMapLayer()`; default is `"feature"`. */
6
+ type?: "feature" | "map-layer";
7
+ /** The query request payload. */
8
+ request: QueryFeaturesRequest | MapLayerQueryRequest;
9
+ /** Optional label to identify this query in the results. */
10
+ label?: string;
11
+ }
12
+ /** The result of a single query within a batch. */
13
+ export interface BatchQueryResult {
14
+ /** The label from the corresponding `BatchQueryItem`, if provided. */
15
+ label?: string;
16
+ /** The successful query response, or `undefined` if the query failed. */
17
+ response?: HonuaQueryResponse;
18
+ /** The error thrown by the query, or `undefined` if the query succeeded. */
19
+ error?: Error;
20
+ }
21
+ /** Options for controlling batch query execution. */
22
+ export interface BatchQueryOptions {
23
+ /** Maximum number of concurrent queries. Default: `5`. */
24
+ concurrency?: number;
25
+ /** An `AbortSignal` that, when aborted, skips all remaining unstarted queries. */
26
+ signal?: AbortSignal;
27
+ }
28
+ /**
29
+ * Execute multiple queries in parallel with bounded concurrency.
30
+ *
31
+ * Results are returned in the same order as the input `items`.
32
+ * Each result contains either a `response` (on success) or an `error` (on failure).
33
+ * If an `AbortSignal` is provided and aborted, remaining unstarted queries are
34
+ * skipped and their results will have an `error` set to an `AbortError`.
35
+ */
36
+ export declare function batchQuery(client: HonuaClient, items: readonly BatchQueryItem[], options?: BatchQueryOptions): Promise<BatchQueryResult[]>;
37
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../../src/core/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEjG,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAC/B,iCAAiC;IACjC,OAAO,EAAE,oBAAoB,GAAG,oBAAoB,CAAC;IACrD,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,4EAA4E;IAC5E,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiF7B"}
package/core/batch.js ADDED
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Execute multiple queries in parallel with bounded concurrency.
3
+ *
4
+ * Results are returned in the same order as the input `items`.
5
+ * Each result contains either a `response` (on success) or an `error` (on failure).
6
+ * If an `AbortSignal` is provided and aborted, remaining unstarted queries are
7
+ * skipped and their results will have an `error` set to an `AbortError`.
8
+ */
9
+ export async function batchQuery(client, items, options) {
10
+ const concurrency = Math.max(1, options?.concurrency ?? 5);
11
+ const signal = options?.signal;
12
+ const results = new Array(items.length);
13
+ // Simple semaphore: track how many queries are currently in-flight.
14
+ let running = 0;
15
+ const queue = [];
16
+ function release() {
17
+ running--;
18
+ const next = queue.shift();
19
+ if (next) {
20
+ next();
21
+ }
22
+ }
23
+ function acquire() {
24
+ if (running < concurrency) {
25
+ running++;
26
+ return Promise.resolve();
27
+ }
28
+ return new Promise((resolve) => {
29
+ queue.push(() => {
30
+ running++;
31
+ resolve();
32
+ });
33
+ });
34
+ }
35
+ const promises = [];
36
+ for (let i = 0; i < items.length; i++) {
37
+ const index = i;
38
+ const item = items[index];
39
+ const task = async () => {
40
+ // Check abort before acquiring a semaphore slot.
41
+ if (signal?.aborted) {
42
+ results[index] = {
43
+ label: item.label,
44
+ error: new DOMException("The operation was aborted.", "AbortError"),
45
+ };
46
+ return;
47
+ }
48
+ await acquire();
49
+ // Check abort again after acquiring the slot.
50
+ if (signal?.aborted) {
51
+ release();
52
+ results[index] = {
53
+ label: item.label,
54
+ error: new DOMException("The operation was aborted.", "AbortError"),
55
+ };
56
+ return;
57
+ }
58
+ try {
59
+ const response = item.type === "map-layer"
60
+ ? await client.queryMapLayer(item.request)
61
+ : await client.queryFeatures(item.request);
62
+ results[index] = { label: item.label, response };
63
+ }
64
+ catch (err) {
65
+ results[index] = {
66
+ label: item.label,
67
+ error: err instanceof Error ? err : new Error(String(err)),
68
+ };
69
+ }
70
+ finally {
71
+ release();
72
+ }
73
+ };
74
+ promises.push(task());
75
+ }
76
+ await Promise.all(promises);
77
+ return results;
78
+ }
@@ -0,0 +1,76 @@
1
+ export type HonuaCacheScope = "metadata" | "materialized-result";
2
+ export type HonuaCacheStatus = "hit" | "miss" | "stale" | "refreshed" | "bypass";
3
+ export type HonuaCacheReadMode = "default" | "bypass";
4
+ export interface HonuaCacheValidator {
5
+ readonly etag?: string;
6
+ readonly lastModified?: string;
7
+ }
8
+ export interface HonuaCacheState {
9
+ readonly scope: HonuaCacheScope;
10
+ readonly status: HonuaCacheStatus;
11
+ readonly keyFingerprint: string;
12
+ readonly ageMs?: number;
13
+ readonly ttlMs?: number;
14
+ readonly staleIfErrorMs?: number;
15
+ readonly revalidatedAt?: string;
16
+ readonly sourceUpdatedAt?: string;
17
+ readonly validator?: HonuaCacheValidator;
18
+ readonly invalidationReason?: string;
19
+ readonly refreshErrorId?: string;
20
+ }
21
+ export interface HonuaMetadataRequestOptions {
22
+ readonly signal?: AbortSignal;
23
+ /**
24
+ * Revalidate even when an SDK-local metadata entry is present. Adapters send
25
+ * conditional validators when available and report `refreshed` on success.
26
+ */
27
+ readonly refresh?: boolean;
28
+ /**
29
+ * `default` reads and writes the adapter metadata cache. `bypass` skips cache
30
+ * lookup and write-through for endpoints that support SDK-local caching.
31
+ */
32
+ readonly cache?: HonuaCacheReadMode;
33
+ /**
34
+ * Allow a cached metadata entry to be returned as `stale` when refresh fails.
35
+ * Defaults to `true`; ignored when no cached metadata entry exists.
36
+ */
37
+ readonly staleIfError?: boolean;
38
+ /** Optional freshness budget surfaced to callers in `HonuaCacheState`. */
39
+ readonly ttlMs?: number;
40
+ /** Optional stale fallback window surfaced to callers in `HonuaCacheState`. */
41
+ readonly staleIfErrorMs?: number;
42
+ }
43
+ export interface NormalizedHonuaMetadataRequestOptions {
44
+ readonly signal?: AbortSignal;
45
+ readonly refresh: boolean;
46
+ readonly cache: HonuaCacheReadMode;
47
+ readonly staleIfError: boolean;
48
+ readonly ttlMs?: number;
49
+ readonly staleIfErrorMs?: number;
50
+ }
51
+ export interface HonuaCacheStateInit {
52
+ readonly scope: HonuaCacheScope;
53
+ readonly status: HonuaCacheStatus;
54
+ readonly keyFingerprint: string;
55
+ readonly ageMs?: number;
56
+ readonly ttlMs?: number;
57
+ readonly staleIfErrorMs?: number;
58
+ readonly revalidatedAt?: string;
59
+ readonly sourceUpdatedAt?: string;
60
+ readonly validator?: HonuaCacheValidator;
61
+ readonly invalidationReason?: string;
62
+ readonly refreshErrorId?: string;
63
+ }
64
+ export declare function createHonuaCacheState(init: HonuaCacheStateInit): HonuaCacheState;
65
+ export declare function normalizeHonuaMetadataRequestOptions(options?: HonuaMetadataRequestOptions): NormalizedHonuaMetadataRequestOptions;
66
+ export declare function isHonuaCacheStatus(value: unknown): value is HonuaCacheStatus;
67
+ export declare function honuaCacheValidatorFromHeaders(headers: Headers): HonuaCacheValidator | undefined;
68
+ export declare function honuaMetadataRequestHeaders(options: {
69
+ readonly accept?: string;
70
+ readonly refresh?: boolean;
71
+ readonly bypass?: boolean;
72
+ readonly validator?: HonuaCacheValidator;
73
+ }): Record<string, string>;
74
+ export declare function withHonuaCacheState<T>(value: T, cache: HonuaCacheState): T;
75
+ export declare function withoutHonuaCacheState<T>(value: T): T;
76
+ //# sourceMappingURL=cache-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-state.d.ts","sourceRoot":"","sources":["../../../src/core/cache-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ export function createHonuaCacheState(init) {
2
+ return {
3
+ scope: init.scope,
4
+ status: init.status,
5
+ keyFingerprint: init.keyFingerprint,
6
+ ...(init.ageMs !== undefined ? { ageMs: Math.max(0, Math.trunc(init.ageMs)) } : {}),
7
+ ...(init.ttlMs !== undefined ? { ttlMs: Math.max(0, Math.trunc(init.ttlMs)) } : {}),
8
+ ...(init.staleIfErrorMs !== undefined ? { staleIfErrorMs: Math.max(0, Math.trunc(init.staleIfErrorMs)) } : {}),
9
+ ...(init.revalidatedAt ? { revalidatedAt: init.revalidatedAt } : {}),
10
+ ...(init.sourceUpdatedAt ? { sourceUpdatedAt: init.sourceUpdatedAt } : {}),
11
+ ...(hasHonuaCacheValidator(init.validator) ? { validator: init.validator } : {}),
12
+ ...(init.invalidationReason ? { invalidationReason: init.invalidationReason } : {}),
13
+ ...(init.refreshErrorId ? { refreshErrorId: init.refreshErrorId } : {}),
14
+ };
15
+ }
16
+ export function normalizeHonuaMetadataRequestOptions(options = {}) {
17
+ return {
18
+ ...(options.signal ? { signal: options.signal } : {}),
19
+ refresh: options.refresh === true,
20
+ cache: options.cache === "bypass" ? "bypass" : "default",
21
+ staleIfError: options.staleIfError !== false,
22
+ ...(normalizeNonNegativeInteger(options.ttlMs) !== undefined
23
+ ? { ttlMs: normalizeNonNegativeInteger(options.ttlMs) }
24
+ : {}),
25
+ ...(normalizeNonNegativeInteger(options.staleIfErrorMs) !== undefined
26
+ ? { staleIfErrorMs: normalizeNonNegativeInteger(options.staleIfErrorMs) }
27
+ : {}),
28
+ };
29
+ }
30
+ export function isHonuaCacheStatus(value) {
31
+ return value === "hit" || value === "miss" || value === "stale" || value === "refreshed" || value === "bypass";
32
+ }
33
+ export function honuaCacheValidatorFromHeaders(headers) {
34
+ const etag = headers.get("etag") ?? undefined;
35
+ const lastModified = headers.get("last-modified") ?? undefined;
36
+ return hasHonuaCacheValidator({ etag, lastModified })
37
+ ? { ...(etag ? { etag } : {}), ...(lastModified ? { lastModified } : {}) }
38
+ : undefined;
39
+ }
40
+ export function honuaMetadataRequestHeaders(options) {
41
+ const headers = {
42
+ Accept: options.accept ?? "application/json",
43
+ };
44
+ if (options.bypass) {
45
+ headers["Cache-Control"] = "no-store";
46
+ headers.Pragma = "no-cache";
47
+ return headers;
48
+ }
49
+ if (options.refresh) {
50
+ headers["Cache-Control"] = "no-cache";
51
+ if (options.validator?.etag) {
52
+ headers["If-None-Match"] = options.validator.etag;
53
+ }
54
+ if (options.validator?.lastModified) {
55
+ headers["If-Modified-Since"] = options.validator.lastModified;
56
+ }
57
+ }
58
+ return headers;
59
+ }
60
+ export function withHonuaCacheState(value, cache) {
61
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
62
+ return value;
63
+ }
64
+ return {
65
+ ...value,
66
+ cache,
67
+ };
68
+ }
69
+ export function withoutHonuaCacheState(value) {
70
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
71
+ return value;
72
+ }
73
+ const { cache: _cache, ...rest } = value;
74
+ return rest;
75
+ }
76
+ function hasHonuaCacheValidator(value) {
77
+ return Boolean(value?.etag || value?.lastModified);
78
+ }
79
+ function normalizeNonNegativeInteger(value) {
80
+ if (typeof value !== "number" || !Number.isFinite(value)) {
81
+ return undefined;
82
+ }
83
+ return Math.max(0, Math.trunc(value));
84
+ }