@honua/react 0.1.7-beta.0 → 0.1.10-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 (249) hide show
  1. package/control-plane/admin-client.d.ts +89 -0
  2. package/control-plane/admin-client.d.ts.map +1 -0
  3. package/control-plane/admin-client.js +200 -0
  4. package/control-plane/client.d.ts +1 -1
  5. package/control-plane/client.d.ts.map +1 -1
  6. package/control-plane/client.js +145 -11
  7. package/control-plane/commands/catalog.d.ts +133 -0
  8. package/control-plane/commands/catalog.d.ts.map +1 -0
  9. package/control-plane/commands/catalog.js +365 -0
  10. package/control-plane/commands/errors.d.ts +96 -0
  11. package/control-plane/commands/errors.d.ts.map +1 -0
  12. package/control-plane/commands/errors.js +130 -0
  13. package/control-plane/commands/identity.d.ts +71 -0
  14. package/control-plane/commands/identity.d.ts.map +1 -0
  15. package/control-plane/commands/identity.js +0 -0
  16. package/control-plane/commands/index.d.ts +39 -0
  17. package/control-plane/commands/index.d.ts.map +1 -0
  18. package/control-plane/commands/index.js +34 -0
  19. package/control-plane/commands/runtime.d.ts +146 -0
  20. package/control-plane/commands/runtime.d.ts.map +1 -0
  21. package/control-plane/commands/runtime.js +330 -0
  22. package/control-plane/commands/types.d.ts +228 -0
  23. package/control-plane/commands/types.d.ts.map +1 -0
  24. package/control-plane/commands/types.js +30 -0
  25. package/control-plane/commands/validate.d.ts +27 -0
  26. package/control-plane/commands/validate.d.ts.map +1 -0
  27. package/control-plane/commands/validate.js +132 -0
  28. package/control-plane/generated/admin-api.d.ts +30265 -0
  29. package/control-plane/generated/admin-api.d.ts.map +1 -0
  30. package/control-plane/generated/admin-api.js +5 -0
  31. package/control-plane/generated/admin-operations.d.ts +4053 -0
  32. package/control-plane/generated/admin-operations.d.ts.map +1 -0
  33. package/control-plane/generated/admin-operations.js +820 -0
  34. package/control-plane/index.d.ts +11 -0
  35. package/control-plane/index.d.ts.map +1 -1
  36. package/control-plane/index.js +8 -0
  37. package/control-plane/types.d.ts +14 -0
  38. package/control-plane/types.d.ts.map +1 -1
  39. package/core/client.d.ts.map +1 -1
  40. package/core/client.js +29 -31
  41. package/core/credential-redaction.d.ts +163 -0
  42. package/core/credential-redaction.d.ts.map +1 -0
  43. package/core/credential-redaction.js +389 -0
  44. package/core/error-classifications.d.ts +15 -0
  45. package/core/error-classifications.d.ts.map +1 -1
  46. package/core/error-classifications.js +15 -0
  47. package/core/error-code-registry.d.ts +15 -0
  48. package/core/error-code-registry.d.ts.map +1 -1
  49. package/core/error-code-registry.js +15 -0
  50. package/core/error-envelope.d.ts +31 -0
  51. package/core/error-envelope.d.ts.map +1 -1
  52. package/core/error-envelope.js +11 -0
  53. package/core/errors.d.ts +15 -3
  54. package/core/errors.d.ts.map +1 -1
  55. package/core/errors.js +254 -2
  56. package/core/geometry-input-sr.d.ts +3 -0
  57. package/core/geometry-input-sr.d.ts.map +1 -0
  58. package/core/geometry-input-sr.js +28 -0
  59. package/core/geoservices.d.ts.map +1 -1
  60. package/core/geoservices.js +33 -6
  61. package/core/grpc-adapter.d.ts +2 -2
  62. package/core/grpc-adapter.d.ts.map +1 -1
  63. package/core/grpc-adapter.js +41 -9
  64. package/core/job-run-errors.d.ts +10 -0
  65. package/core/job-run-errors.d.ts.map +1 -0
  66. package/core/job-run-errors.js +14 -0
  67. package/core/job-run-lifecycle.d.ts +34 -0
  68. package/core/job-run-lifecycle.d.ts.map +1 -0
  69. package/core/job-run-lifecycle.js +193 -0
  70. package/core/ogc-processes.d.ts +38 -31
  71. package/core/ogc-processes.d.ts.map +1 -1
  72. package/core/ogc-processes.js +123 -173
  73. package/core/pbf-decoder.d.ts.map +1 -1
  74. package/core/pbf-decoder.js +16 -4
  75. package/core/process-runner.js +15 -100
  76. package/core/protocol-transport.d.ts +6 -1
  77. package/core/protocol-transport.d.ts.map +1 -1
  78. package/core/request-pipeline.d.ts +6 -3
  79. package/core/request-pipeline.d.ts.map +1 -1
  80. package/core/request-pipeline.js +28 -11
  81. package/core/spatial-filter.d.ts +4 -4
  82. package/core/spatial-filter.d.ts.map +1 -1
  83. package/core/spatial-filter.js +7 -7
  84. package/core/surfaces.d.ts +2 -8
  85. package/core/surfaces.d.ts.map +1 -1
  86. package/core/surfaces.js +21 -112
  87. package/core/types.d.ts +21 -9
  88. package/core/types.d.ts.map +1 -1
  89. package/esri-compat/class-breaks-renderer.d.ts +2 -0
  90. package/esri-compat/class-breaks-renderer.d.ts.map +1 -1
  91. package/esri-compat/class-breaks-renderer.js +7 -0
  92. package/esri-compat/controls.d.ts +10 -1
  93. package/esri-compat/controls.d.ts.map +1 -1
  94. package/esri-compat/controls.js +86 -2
  95. package/esri-compat/directions.d.ts +35 -0
  96. package/esri-compat/directions.d.ts.map +1 -1
  97. package/esri-compat/directions.js +153 -2
  98. package/esri-compat/expand.d.ts +1 -0
  99. package/esri-compat/expand.d.ts.map +1 -1
  100. package/esri-compat/expand.js +61 -0
  101. package/esri-compat/feature-layer.d.ts +29 -4
  102. package/esri-compat/feature-layer.d.ts.map +1 -1
  103. package/esri-compat/feature-layer.js +335 -13
  104. package/esri-compat/geometry-engine.d.ts +4 -0
  105. package/esri-compat/geometry-engine.d.ts.map +1 -1
  106. package/esri-compat/geometry-engine.js +8 -1
  107. package/esri-compat/graphic.d.ts +7 -4
  108. package/esri-compat/graphic.d.ts.map +1 -1
  109. package/esri-compat/legend.d.ts +2 -1
  110. package/esri-compat/legend.d.ts.map +1 -1
  111. package/esri-compat/legend.js +15 -0
  112. package/esri-compat/map-view-mount.d.ts +48 -0
  113. package/esri-compat/map-view-mount.d.ts.map +1 -0
  114. package/esri-compat/map-view-mount.js +344 -0
  115. package/esri-compat/map-view.d.ts +38 -6
  116. package/esri-compat/map-view.d.ts.map +1 -1
  117. package/esri-compat/map-view.js +467 -33
  118. package/esri-compat/portal.d.ts +2 -0
  119. package/esri-compat/portal.d.ts.map +1 -1
  120. package/esri-compat/portal.js +7 -2
  121. package/esri-compat/renderer-objects.d.ts +7 -2
  122. package/esri-compat/renderer-objects.d.ts.map +1 -1
  123. package/esri-compat/renderer-objects.js +16 -5
  124. package/esri-compat/route-layer.d.ts +8 -0
  125. package/esri-compat/route-layer.d.ts.map +1 -1
  126. package/esri-compat/route-layer.js +24 -4
  127. package/esri-compat/route-task.d.ts +5 -1
  128. package/esri-compat/route-task.d.ts.map +1 -1
  129. package/esri-compat/route-task.js +119 -7
  130. package/esri-compat/scene-view.d.ts.map +1 -1
  131. package/esri-compat/scene-view.js +1 -0
  132. package/esri-compat/search.d.ts +2 -1
  133. package/esri-compat/search.d.ts.map +1 -1
  134. package/esri-compat/search.js +52 -2
  135. package/esri-compat/unique-value-renderer.d.ts +2 -0
  136. package/esri-compat/unique-value-renderer.d.ts.map +1 -1
  137. package/esri-compat/unique-value-renderer.js +7 -0
  138. package/esri-compat/web-map.d.ts +10 -0
  139. package/esri-compat/web-map.d.ts.map +1 -1
  140. package/esri-compat/web-map.js +102 -0
  141. package/gen/geospatial/v1/common_pb.d.ts +514 -0
  142. package/gen/geospatial/v1/common_pb.d.ts.map +1 -0
  143. package/gen/geospatial/v1/common_pb.js +335 -0
  144. package/gen/geospatial/v1/execution_types_pb.d.ts +1186 -0
  145. package/gen/geospatial/v1/execution_types_pb.d.ts.map +1 -0
  146. package/gen/geospatial/v1/execution_types_pb.js +396 -0
  147. package/gen/geospatial/v1/feature_service_pb.d.ts +403 -0
  148. package/gen/geospatial/v1/feature_service_pb.d.ts.map +1 -0
  149. package/gen/geospatial/v1/feature_service_pb.js +47 -0
  150. package/gen/geospatial/v1/index.d.ts +5 -0
  151. package/gen/geospatial/v1/index.d.ts.map +1 -0
  152. package/gen/geospatial/v1/index.js +9 -0
  153. package/gen/geospatial/v1/spatial_types_pb.d.ts +285 -0
  154. package/gen/geospatial/v1/spatial_types_pb.d.ts.map +1 -0
  155. package/gen/geospatial/v1/spatial_types_pb.js +58 -0
  156. package/gen/geospatial/v1/workspace_artifact_types_pb.d.ts +379 -0
  157. package/gen/geospatial/v1/workspace_artifact_types_pb.d.ts.map +1 -0
  158. package/gen/geospatial/v1/workspace_artifact_types_pb.js +151 -0
  159. package/generated-app/projection.d.ts.map +1 -1
  160. package/generated-app/projection.js +10 -1
  161. package/map/webmap-maplibre.d.ts +2 -1
  162. package/map/webmap-maplibre.d.ts.map +1 -1
  163. package/map/webmap-maplibre.js +3 -0
  164. package/package.json +3 -3
  165. package/query-planner/geoservices.d.ts.map +1 -1
  166. package/query-planner/geoservices.js +2 -0
  167. package/query-planner/grpc.d.ts +4 -4
  168. package/query-planner/grpc.d.ts.map +1 -1
  169. package/query-planner/grpc.js +11 -11
  170. package/query-planner/types.d.ts +6 -4
  171. package/query-planner/types.d.ts.map +1 -1
  172. package/realtime/honua-server.d.ts +4 -0
  173. package/realtime/honua-server.d.ts.map +1 -1
  174. package/realtime/honua-server.js +10 -0
  175. package/realtime/resumable.js +9 -0
  176. package/realtime/types.d.ts +8 -0
  177. package/realtime/types.d.ts.map +1 -1
  178. package/runtime/errors.d.ts +1 -1
  179. package/runtime/errors.d.ts.map +1 -1
  180. package/runtime/errors.js +2 -0
  181. package/runtime/generated/map-package-schema-meta.d.ts +11 -0
  182. package/runtime/generated/map-package-schema-meta.d.ts.map +1 -0
  183. package/runtime/generated/map-package-schema-meta.js +12 -0
  184. package/runtime/generated/map-package-schema-validator.d.ts +16 -0
  185. package/runtime/generated/map-package-schema-validator.d.ts.map +1 -0
  186. package/runtime/generated/map-package-schema-validator.js +1422 -0
  187. package/runtime/index.d.ts +5 -1
  188. package/runtime/index.d.ts.map +1 -1
  189. package/runtime/index.js +6 -0
  190. package/runtime/map-package-export.d.ts +151 -0
  191. package/runtime/map-package-export.d.ts.map +1 -0
  192. package/runtime/map-package-export.js +636 -0
  193. package/runtime/map-package-validation.d.ts +21 -1
  194. package/runtime/map-package-validation.d.ts.map +1 -1
  195. package/runtime/map-package-validation.js +132 -95
  196. package/runtime/map-package.d.ts +80 -0
  197. package/runtime/map-package.d.ts.map +1 -1
  198. package/studio/capability-manifest.d.ts +10 -0
  199. package/studio/capability-manifest.d.ts.map +1 -1
  200. package/studio/capability-manifest.js +38 -0
  201. package/studio/chart-spec.d.ts +6 -6
  202. package/studio/chart-spec.d.ts.map +1 -1
  203. package/studio/chart-spec.js +6 -6
  204. package/studio/command-adapter.d.ts +35 -0
  205. package/studio/command-adapter.d.ts.map +1 -0
  206. package/studio/command-adapter.js +36 -0
  207. package/studio/generated/studio-api.d.ts +1062 -0
  208. package/studio/generated/studio-api.d.ts.map +1 -0
  209. package/studio/generated/studio-api.js +4 -0
  210. package/studio/index.d.ts +25 -13
  211. package/studio/index.d.ts.map +1 -1
  212. package/studio/index.js +21 -10
  213. package/studio/lifecycle-client.d.ts +262 -22
  214. package/studio/lifecycle-client.d.ts.map +1 -1
  215. package/studio/lifecycle-client.js +543 -24
  216. package/studio/lifecycle-errors.d.ts +8 -2
  217. package/studio/lifecycle-errors.d.ts.map +1 -1
  218. package/studio/lifecycle-errors.js +6 -1
  219. package/studio/lifecycle-types.d.ts +237 -38
  220. package/studio/lifecycle-types.d.ts.map +1 -1
  221. package/studio/lifecycle-types.js +5 -12
  222. package/studio/publication-status.d.ts +55 -0
  223. package/studio/publication-status.d.ts.map +1 -0
  224. package/studio/publication-status.js +103 -0
  225. package/studio/types.d.ts +37 -7
  226. package/studio/types.d.ts.map +1 -1
  227. package/studio/types.js +5 -3
  228. package/studio/validate.d.ts.map +1 -1
  229. package/studio/validate.js +104 -7
  230. package/style/renderers.d.ts +6 -1
  231. package/style/renderers.d.ts.map +1 -1
  232. package/style/renderers.js +11 -6
  233. package/style/visual-variables.d.ts +43 -0
  234. package/style/visual-variables.d.ts.map +1 -0
  235. package/style/visual-variables.js +183 -0
  236. package/webmap/convert-layer.d.ts +2 -1
  237. package/webmap/convert-layer.d.ts.map +1 -1
  238. package/webmap/convert-layer.js +20 -3
  239. package/webmap/convert-renderer.d.ts +10 -3
  240. package/webmap/convert-renderer.d.ts.map +1 -1
  241. package/webmap/convert-renderer.js +190 -36
  242. package/webmap/index.d.ts +1 -0
  243. package/webmap/index.d.ts.map +1 -1
  244. package/webmap/parse.d.ts +2 -1
  245. package/webmap/parse.d.ts.map +1 -1
  246. package/webmap/parse.js +1 -1
  247. package/gen/honua/v1/feature_service_pb.d.ts +0 -918
  248. package/gen/honua/v1/feature_service_pb.d.ts.map +0 -1
  249. package/gen/honua/v1/feature_service_pb.js +0 -375
@@ -1,4 +1,5 @@
1
1
  import { HonuaClient } from "../core/client.js";
2
+ import { HonuaCapabilityNotSupportedError } from "../core/errors.js";
2
3
  import { encodeServiceIdPath } from "../core/path-utils.js";
3
4
  import { responseExceededTransferLimit } from "../core/wire-shared.js";
4
5
  import { CompatEventBus, resolveCompatEventBus, safeInvokeCompatListener } from "./event-bus.js";
@@ -6,6 +7,10 @@ import { parseFeatureLayerUrl } from "./url.js";
6
7
  const DEFAULT_MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
7
8
  export class FeatureLayerCompat {
8
9
  url;
10
+ source;
11
+ fields;
12
+ objectIdField;
13
+ geometryType;
9
14
  id;
10
15
  title;
11
16
  serviceId;
@@ -22,6 +27,8 @@ export class FeatureLayerCompat {
22
27
  maxScale;
23
28
  legendEnabled;
24
29
  listMode;
30
+ /** Populated from layer metadata `extent` when {@link load} succeeds. */
31
+ fullExtent;
25
32
  loaded;
26
33
  loadStatus;
27
34
  metadata;
@@ -32,11 +39,16 @@ export class FeatureLayerCompat {
32
39
  eventListeners;
33
40
  maxAttachmentBytes;
34
41
  constructor(options) {
35
- const parsed = parseFeatureLayerUrl(options.url);
42
+ const inMemory = options.source !== undefined && options.url === undefined;
43
+ const parsed = inMemory ? undefined : parseFeatureLayerUrl(options.url ?? "");
36
44
  this.url = options.url;
37
- this.serviceId = parsed.serviceId;
38
- this.layerId = parsed.layerId;
39
- this.id = options.id ?? `${this.serviceId}-${this.layerId}`;
45
+ this.source = options.source === undefined ? undefined : [...options.source];
46
+ this.fields = options.fields === undefined ? undefined : [...options.fields];
47
+ this.objectIdField = options.objectIdField;
48
+ this.geometryType = options.geometryType;
49
+ this.serviceId = parsed?.serviceId ?? "memory";
50
+ this.layerId = parsed?.layerId ?? 0;
51
+ this.id = options.id ?? (parsed ? `${this.serviceId}-${this.layerId}` : "memory-feature-layer");
40
52
  this.title = options.title;
41
53
  this.outFields =
42
54
  options.outFields === undefined
@@ -47,20 +59,25 @@ export class FeatureLayerCompat {
47
59
  this.definitionExpression = options.definitionExpression;
48
60
  this.renderer = options.renderer;
49
61
  this.popupTemplate = options.popupTemplate;
50
- this.labelingInfo = Array.isArray(options.labelingInfo) ? [...options.labelingInfo] : [];
62
+ this.labelingInfo = Array.isArray(options.labelingInfo)
63
+ ? [...options.labelingInfo]
64
+ : options.labelingInfo === undefined
65
+ ? []
66
+ : [options.labelingInfo];
51
67
  this.labelsVisible = options.labelsVisible ?? true;
52
68
  this.opacity = normalizeOpacity(options.opacity ?? 1);
53
69
  this.visible = options.visible ?? true;
54
70
  this.minScale = normalizeScale(options.minScale);
55
71
  this.maxScale = normalizeScale(options.maxScale);
56
72
  this.legendEnabled = options.legendEnabled ?? true;
73
+ this.fullExtent = undefined;
57
74
  this.listMode = options.listMode ?? "show";
58
75
  this.loaded = false;
59
76
  this.loadStatus = "not-loaded";
60
77
  this.metadata = undefined;
61
78
  this.timeExtent = undefined;
62
79
  this.eventBus = options.eventBus ?? resolveCompatEventBus(options.client) ?? new CompatEventBus();
63
- this.client = options.client ?? new HonuaClient({ baseUrl: parsed.baseUrl });
80
+ this.client = options.client ?? new HonuaClient({ baseUrl: parsed?.baseUrl ?? "https://memory.invalid" });
64
81
  this.watchListeners = new Map();
65
82
  this.eventListeners = new Map();
66
83
  this.maxAttachmentBytes = normalizeAttachmentSizeLimit(options.maxAttachmentBytes);
@@ -71,8 +88,12 @@ export class FeatureLayerCompat {
71
88
  this.notifyWatchers("loadStatus", this.loadStatus);
72
89
  this.eventBus.emit("feature-layer.loading", { serviceId: this.serviceId, layerId: this.layerId, id: this.id }, this);
73
90
  try {
74
- this.metadata = await this.client.getLayerMetadata(this.serviceId, this.layerId);
91
+ this.metadata = this.isInMemory
92
+ ? { fields: this.fields ?? [] }
93
+ : await this.client.getLayerMetadata(this.serviceId, this.layerId);
75
94
  this.notifyWatchers("metadata", this.metadata);
95
+ this.fullExtent = extentFromMetadata(this.metadata);
96
+ this.notifyWatchers("fullExtent", this.fullExtent);
76
97
  this.loaded = true;
77
98
  this.notifyWatchers("loaded", this.loaded);
78
99
  this.loadStatus = "loaded";
@@ -82,6 +103,8 @@ export class FeatureLayerCompat {
82
103
  catch (error) {
83
104
  this.metadata = undefined;
84
105
  this.notifyWatchers("metadata", this.metadata);
106
+ this.fullExtent = undefined;
107
+ this.notifyWatchers("fullExtent", this.fullExtent);
85
108
  this.loaded = false;
86
109
  this.notifyWatchers("loaded", this.loaded);
87
110
  this.loadStatus = "failed";
@@ -106,6 +129,8 @@ export class FeatureLayerCompat {
106
129
  this.notifyWatchers("loadStatus", this.loadStatus);
107
130
  this.metadata = undefined;
108
131
  this.notifyWatchers("metadata", this.metadata);
132
+ this.fullExtent = undefined;
133
+ this.notifyWatchers("fullExtent", this.fullExtent);
109
134
  this.eventBus.emit("feature-layer.refreshed", { serviceId: this.serviceId, layerId: this.layerId, id: this.id }, this);
110
135
  }
111
136
  watch(propertyName, listener) {
@@ -204,7 +229,7 @@ export class FeatureLayerCompat {
204
229
  };
205
230
  }
206
231
  listFields() {
207
- return extractFieldDefinitions(this.metadata);
232
+ return extractFieldDefinitions(this.isInMemory ? { fields: this.fields } : this.metadata);
208
233
  }
209
234
  getField(fieldName) {
210
235
  const normalizedFieldName = fieldName.trim();
@@ -225,7 +250,54 @@ export class FeatureLayerCompat {
225
250
  returnGeometry: true,
226
251
  };
227
252
  }
253
+ get isInMemory() {
254
+ return this.source !== undefined && this.url === undefined;
255
+ }
256
+ assertSupportedMemoryWhere(where) {
257
+ if (where === undefined) {
258
+ return;
259
+ }
260
+ const clause = where.trim();
261
+ if (clause.length === 0 || /^\s*1\s*=\s*1\s*$/.test(clause)) {
262
+ return;
263
+ }
264
+ for (const part of splitWhereAnd(clause)) {
265
+ if (!isSupportedWhereComparison(part)) {
266
+ throw new HonuaCapabilityNotSupportedError("where", "in-memory", this.id);
267
+ }
268
+ }
269
+ }
270
+ async queryMemory(options) {
271
+ options.signal?.throwIfAborted();
272
+ this.assertSupportedMemoryWhere(this.definitionExpression);
273
+ this.assertSupportedMemoryWhere(options.where);
274
+ if (this.timeExtent)
275
+ throw new HonuaCapabilityNotSupportedError("time", "in-memory", this.id);
276
+ for (const key of Object.keys(options.extraParams ?? {})) {
277
+ if (key !== "resultOffset" && key !== "resultRecordCount") {
278
+ throw new HonuaCapabilityNotSupportedError(key, "in-memory", this.id);
279
+ }
280
+ }
281
+ const source = (this.source ?? []).filter((feature) => featureMatchesWhere(feature, this.definitionExpression) && featureMatchesWhere(feature, options.where));
282
+ const offset = Number(options.extraParams?.resultOffset ?? 0);
283
+ const count = Number(options.extraParams?.resultRecordCount ?? source.length);
284
+ if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(count) || count < 0) {
285
+ throw new RangeError("In-memory pagination requires nonnegative safe integers");
286
+ }
287
+ const requestedFields = options.outFields ?? this.outFields ?? ["*"];
288
+ const fields = (Array.isArray(requestedFields) ? requestedFields : requestedFields.split(",")).map((f) => f.trim());
289
+ return {
290
+ objectIdFieldName: this.objectIdField,
291
+ features: source.slice(offset, offset + count).map((feature) => ({
292
+ attributes: Object.fromEntries(Object.entries(feature.attributes).filter(([key]) => fields.includes("*") || fields.includes(key))),
293
+ ...(options.returnGeometry === false ? {} : { geometry: feature.geometry }),
294
+ })),
295
+ exceededTransferLimit: offset + count < source.length,
296
+ };
297
+ }
228
298
  queryFeatures(options = {}) {
299
+ if (this.isInMemory)
300
+ return this.queryMemory(options);
229
301
  const timeParam = buildTimeParam(this.timeExtent, options.extraParams);
230
302
  return this.client.queryFeatures({
231
303
  serviceId: this.serviceId,
@@ -299,6 +371,12 @@ export class FeatureLayerCompat {
299
371
  }
300
372
  }
301
373
  async queryObjectIds(options = {}) {
374
+ if (this.isInMemory) {
375
+ const { features = [] } = await this.queryMemory({ ...options, outFields: ["*"], returnGeometry: false });
376
+ return features
377
+ .map((feature) => this.objectIdField ? Number(feature.attributes[this.objectIdField]) : extractObjectId(feature))
378
+ .filter((id) => typeof id === "number" && Number.isFinite(id));
379
+ }
302
380
  const response = (await this.client.queryFeatures({
303
381
  serviceId: this.serviceId,
304
382
  layerId: this.layerId,
@@ -320,6 +398,8 @@ export class FeatureLayerCompat {
320
398
  return features.map((feature) => extractObjectId(feature)).filter((value) => value !== undefined);
321
399
  }
322
400
  async queryFeatureCount(options = {}) {
401
+ if (this.isInMemory)
402
+ return (await this.queryMemory(options)).features?.length ?? 0;
323
403
  const response = (await this.client.queryFeatures({
324
404
  serviceId: this.serviceId,
325
405
  layerId: this.layerId,
@@ -337,6 +417,48 @@ export class FeatureLayerCompat {
337
417
  return response.features?.length ?? 0;
338
418
  }
339
419
  async queryExtent(options = {}) {
420
+ if (this.isInMemory) {
421
+ const { features = [] } = await this.queryMemory(options);
422
+ let extent = null;
423
+ for (const { geometry } of features) {
424
+ if (!geometry)
425
+ continue;
426
+ const g = geometry;
427
+ const coordinates = typeof g.x === "number"
428
+ ? [[g.x, g.y]]
429
+ : typeof g.xmin === "number"
430
+ ? [
431
+ [g.xmin, g.ymin],
432
+ [g.xmax, g.ymax],
433
+ ]
434
+ : Array.isArray(g.points)
435
+ ? g.points
436
+ : Array.isArray(g.paths)
437
+ ? g.paths.flat()
438
+ : Array.isArray(g.rings)
439
+ ? g.rings.flat()
440
+ : undefined;
441
+ if (!coordinates)
442
+ throw new HonuaCapabilityNotSupportedError("geometry extent", "in-memory", this.id);
443
+ for (const [x, y] of coordinates) {
444
+ if (!Number.isFinite(x) || !Number.isFinite(y))
445
+ throw new TypeError("Invalid in-memory coordinates");
446
+ if (!extent)
447
+ extent = {
448
+ xmin: x,
449
+ ymin: y,
450
+ xmax: x,
451
+ ymax: y,
452
+ spatialReference: geometry.spatialReference,
453
+ };
454
+ extent.xmin = Math.min(extent.xmin, x);
455
+ extent.ymin = Math.min(extent.ymin, y);
456
+ extent.xmax = Math.max(extent.xmax, x);
457
+ extent.ymax = Math.max(extent.ymax, y);
458
+ }
459
+ }
460
+ return { extent, count: features.length };
461
+ }
340
462
  const response = (await this.client.queryFeatures({
341
463
  serviceId: this.serviceId,
342
464
  layerId: this.layerId,
@@ -355,14 +477,22 @@ export class FeatureLayerCompat {
355
477
  };
356
478
  }
357
479
  async applyEdits(options) {
358
- const result = await this.client.applyEdits({
480
+ const adds = options.adds ?? options.addFeatures;
481
+ const updates = options.updates ?? options.updateFeatures;
482
+ const deletes = normalizeEditDeletes(options.deletes ?? options.deleteFeatures, this.objectIdField);
483
+ if (this.isInMemory) {
484
+ const result = withEsriEditNames(applyMemoryEdits(this.source, this.objectIdField, adds, updates, deletes));
485
+ this.eventBus.emit("feature-layer.edits", { result, layerId: this.id }, this);
486
+ return result;
487
+ }
488
+ const result = withEsriEditNames(await this.client.applyEdits({
359
489
  serviceId: this.serviceId,
360
490
  layerId: this.layerId,
361
- adds: options.adds,
362
- updates: options.updates,
363
- deletes: options.deletes,
491
+ adds: adds,
492
+ updates: updates,
493
+ deletes,
364
494
  rollbackOnFailure: options.rollbackOnFailure,
365
- });
495
+ }));
366
496
  this.eventBus.emit("feature-layer.edits", { result, layerId: this.id }, this);
367
497
  return result;
368
498
  }
@@ -479,6 +609,30 @@ export class FeatureLayerCompat {
479
609
  }
480
610
  }
481
611
  }
612
+ function finiteNumber(value) {
613
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
614
+ }
615
+ function extentFromMetadata(metadata) {
616
+ if (!isRecord(metadata) || !isRecord(metadata.extent)) {
617
+ return undefined;
618
+ }
619
+ const xmin = finiteNumber(metadata.extent.xmin);
620
+ const ymin = finiteNumber(metadata.extent.ymin);
621
+ const xmax = finiteNumber(metadata.extent.xmax);
622
+ const ymax = finiteNumber(metadata.extent.ymax);
623
+ if (xmin === undefined || ymin === undefined || xmax === undefined || ymax === undefined) {
624
+ return undefined;
625
+ }
626
+ const spatialReference = isRecord(metadata.extent.spatialReference) ? metadata.extent.spatialReference : undefined;
627
+ const wkid = spatialReference ? finiteNumber(spatialReference.wkid) : undefined;
628
+ return {
629
+ xmin,
630
+ ymin,
631
+ xmax,
632
+ ymax,
633
+ ...(wkid === undefined ? {} : { spatialReference: { wkid } }),
634
+ };
635
+ }
482
636
  function isRecord(value) {
483
637
  return typeof value === "object" && value !== null;
484
638
  }
@@ -660,3 +814,171 @@ function copyToArrayBuffer(chunk) {
660
814
  copy.set(chunk);
661
815
  return copy.buffer;
662
816
  }
817
+ function featureAttributes(feature) {
818
+ if (!feature || typeof feature !== "object") {
819
+ return {};
820
+ }
821
+ const attributes = feature.attributes;
822
+ return attributes && typeof attributes === "object" ? attributes : {};
823
+ }
824
+ function featureObjectId(feature, objectIdField) {
825
+ const attributes = featureAttributes(feature);
826
+ const raw = attributes[objectIdField ?? "OBJECTID"] ?? attributes.OBJECTID ?? attributes.objectId;
827
+ const value = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : Number.NaN;
828
+ return Number.isFinite(value) ? value : undefined;
829
+ }
830
+ function featureMatchesWhere(feature, where) {
831
+ const clause = (where ?? "1=1").trim();
832
+ if (clause.length === 0 || clause === "1=1" || clause.replace(/\s+/g, "").toLowerCase() === "1=1") {
833
+ return true;
834
+ }
835
+ return splitWhereAnd(clause).every((part) => featureMatchesComparison(feature, part));
836
+ }
837
+ function splitWhereAnd(where) {
838
+ const parts = [];
839
+ let current = "";
840
+ let quote;
841
+ for (let index = 0; index < where.length; index += 1) {
842
+ const char = where[index] ?? "";
843
+ if (quote) {
844
+ current += char;
845
+ if (char === quote) {
846
+ if (where[index + 1] === quote) {
847
+ current += quote;
848
+ index += 1;
849
+ }
850
+ else {
851
+ quote = undefined;
852
+ }
853
+ }
854
+ continue;
855
+ }
856
+ if (char === "'" || char === '"') {
857
+ quote = char;
858
+ current += char;
859
+ continue;
860
+ }
861
+ if (where.slice(index, index + 5).toLowerCase() === " and ") {
862
+ parts.push(current.trim());
863
+ current = "";
864
+ index += 4;
865
+ continue;
866
+ }
867
+ current += char;
868
+ }
869
+ if (current.trim().length > 0) {
870
+ parts.push(current.trim());
871
+ }
872
+ return parts;
873
+ }
874
+ function isSupportedWhereComparison(comparison) {
875
+ return /^([A-Za-z_][\w.]*)\s*(=|like)\s*('(?:[^']|'')*'|"(?:[^"]|"")*"|-?\d+(?:\.\d+)?)$/i.test(comparison.trim());
876
+ }
877
+ function featureMatchesComparison(feature, comparison) {
878
+ const match = /^([A-Za-z_][\w.]*)\s*(=|like)\s*('(?:[^']|'')*'|"(?:[^"]|"")*"|-?\d+(?:\.\d+)?)$/i.exec(comparison.trim());
879
+ if (!match) {
880
+ return false;
881
+ }
882
+ const field = match[1] ?? "";
883
+ const operator = (match[2] ?? "").toLowerCase();
884
+ const expected = unquoteWhereLiteral(match[3] ?? "");
885
+ const attributes = featureAttributes(feature);
886
+ const actual = Object.entries(attributes).find(([name]) => name.toLowerCase() === field.toLowerCase())?.[1];
887
+ const actualText = actual === undefined || actual === null ? "" : String(actual);
888
+ if (operator === "like") {
889
+ const pattern = expected
890
+ .replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
891
+ .replace(/%/g, ".*")
892
+ .replace(/_/g, ".");
893
+ return new RegExp(`^${pattern}$`, "i").test(actualText);
894
+ }
895
+ return (actualText === expected ||
896
+ (expected !== "" && Number(actualText) === Number(expected) && Number.isFinite(Number(expected))));
897
+ }
898
+ function unquoteWhereLiteral(value) {
899
+ const trimmed = value.trim();
900
+ const quote = trimmed[0];
901
+ if ((quote === "'" || quote === '"') && trimmed.endsWith(quote) && trimmed.length >= 2) {
902
+ return trimmed.slice(1, -1).replaceAll(`${quote}${quote}`, quote);
903
+ }
904
+ return trimmed;
905
+ }
906
+ function normalizeEditDeletes(deletes, objectIdField) {
907
+ if (deletes === undefined) {
908
+ return undefined;
909
+ }
910
+ if (typeof deletes === "string") {
911
+ return deletes;
912
+ }
913
+ return deletes
914
+ .map((entry) => objectIdFromEditEntry(entry, objectIdField))
915
+ .filter((value) => value !== undefined);
916
+ }
917
+ function objectIdFromEditEntry(entry, objectIdField) {
918
+ if (typeof entry === "number" && Number.isFinite(entry)) {
919
+ return entry;
920
+ }
921
+ if (!entry || typeof entry !== "object") {
922
+ return undefined;
923
+ }
924
+ const record = entry;
925
+ if (typeof record.objectId === "number" && Number.isFinite(record.objectId)) {
926
+ return record.objectId;
927
+ }
928
+ const attributes = record.attributes;
929
+ if (!attributes) {
930
+ return undefined;
931
+ }
932
+ const raw = attributes[objectIdField ?? "OBJECTID"] ?? attributes.OBJECTID ?? attributes.objectId;
933
+ const value = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : Number.NaN;
934
+ return Number.isFinite(value) ? value : undefined;
935
+ }
936
+ function withEsriEditNames(result) {
937
+ return {
938
+ ...result,
939
+ addFeatureResults: result.addResults,
940
+ updateFeatureResults: result.updateResults,
941
+ deleteFeatureResults: result.deleteResults,
942
+ };
943
+ }
944
+ function applyMemoryEdits(features, objectIdField, adds, updates, deletes) {
945
+ const deleteIds = new Set(Array.isArray(deletes) ? deletes : []);
946
+ const deleteResults = [...deleteIds].map((objectId) => {
947
+ const index = features.findIndex((feature) => featureObjectId(feature, objectIdField) === objectId);
948
+ if (index >= 0) {
949
+ features.splice(index, 1);
950
+ }
951
+ return { objectId, success: index >= 0 };
952
+ });
953
+ let nextId = 0;
954
+ for (const feature of features) {
955
+ nextId = Math.max(nextId, featureObjectId(feature, objectIdField) ?? 0);
956
+ }
957
+ const addResults = (adds ?? []).map((feature) => {
958
+ const existing = featureObjectId(feature, objectIdField);
959
+ const objectId = existing ?? ++nextId;
960
+ if (existing === undefined && feature && typeof feature === "object") {
961
+ const record = feature;
962
+ record.attributes = { ...(record.attributes ?? {}), [objectIdField ?? "OBJECTID"]: objectId };
963
+ }
964
+ features.push(feature);
965
+ return { objectId, success: true };
966
+ });
967
+ const updateResults = (updates ?? []).map((feature) => {
968
+ const objectId = featureObjectId(feature, objectIdField);
969
+ if (objectId === undefined) {
970
+ return { objectId: -1, success: false, error: { code: 400, description: "Update is missing an object id." } };
971
+ }
972
+ const index = features.findIndex((candidate) => featureObjectId(candidate, objectIdField) === objectId);
973
+ if (index < 0) {
974
+ return {
975
+ objectId,
976
+ success: false,
977
+ error: { code: 404, description: "Feature was not in the in-memory source." },
978
+ };
979
+ }
980
+ features[index] = feature;
981
+ return { objectId, success: true };
982
+ });
983
+ return { addResults, updateResults, deleteResults };
984
+ }
@@ -61,6 +61,8 @@ export declare function difference(input: GeometryEngineInput, subtractor: Geome
61
61
  export declare function simplify(input: GeometryEngineInput): EsriGeometry | null;
62
62
  /** Convex hull of a geometry. Backed by `@turf/convex`. */
63
63
  export declare function convexHull(input: GeometryEngineInput): EsriGeometry | null;
64
+ /** Centroid of a geometry. Backed by `@turf/centroid`. */
65
+ export declare function centroid(input: GeometryEngineInput): EsriGeometry | null;
64
66
  /** True if `container` completely contains `inside`. Backed by `@turf/boolean-contains`. */
65
67
  export declare function contains(container: GeometryEngineInput, inside: GeometryEngineInput): boolean;
66
68
  /** True if `a` and `b` intersect. Backed by `@turf/boolean-intersects`. */
@@ -82,6 +84,7 @@ export declare const geometryEngineCompat: {
82
84
  readonly planarLength: typeof planarLength;
83
85
  readonly simplify: typeof simplify;
84
86
  readonly convexHull: typeof convexHull;
87
+ readonly centroid: typeof centroid;
85
88
  readonly contains: typeof contains;
86
89
  readonly intersects: typeof intersects;
87
90
  };
@@ -101,6 +104,7 @@ export declare const geometryEngineAsyncCompat: {
101
104
  readonly planarLength: (input: GeometryEngineInput, unit?: EsriLinearUnit) => Promise<number>;
102
105
  readonly simplify: (input: GeometryEngineInput) => Promise<EsriGeometry | null>;
103
106
  readonly convexHull: (input: GeometryEngineInput) => Promise<EsriGeometry | null>;
107
+ readonly centroid: (input: GeometryEngineInput) => Promise<EsriGeometry | null>;
104
108
  readonly contains: (container: GeometryEngineInput, inside: GeometryEngineInput) => Promise<boolean>;
105
109
  readonly intersects: (a: GeometryEngineInput, b: GeometryEngineInput) => Promise<boolean>;
106
110
  };
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-engine.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/geometry-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,kBAAkB,CAAC;AAgB5E,iFAAiF;AACjF,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG;IAAE,MAAM,IAAI,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAEpH,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjH,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,mBAAmB,GACnB,aAAa,GACb,cAAc,GACd,cAAc,GACd,OAAO,GACP,UAAU,CAAC;AA2Ef,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,YAA8B,GAAG,MAAM,CAKrG;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,YAA8B,GAAG,MAAM,CAInG;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,cAAyB,GAAG,MAAM,CAKlG;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,cAAyB,GAAG,MAAM,CAIhG;AAwDD;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,cAAyB,GAC9B,YAAY,GAAG,IAAI,CAarB;AAED,gEAAgE;AAChE,wBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,YAAY,GAAG,IAAI,CAQjF;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAI3G;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAI3G;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAGxE;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAG1E;AAID,4FAA4F;AAC5F,wBAAgB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAE7F;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAElF;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;CAavB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;6BACpB,mBAAmB,YAAY,MAAM,SAAS,cAAc;gCAEzD,mBAAmB,eAAe,mBAAmB;6BAExD,SAAS,mBAAmB,EAAE;iCAC1B,mBAAmB,cAAc,mBAAmB;mCAElD,mBAAmB,SAAS,YAAY;iCAC1C,mBAAmB,SAAS,YAAY;qCACpC,mBAAmB,SAAS,cAAc;mCAC5C,mBAAmB,SAAS,cAAc;+BAC9C,mBAAmB;iCACjB,mBAAmB;mCACjB,mBAAmB,UAAU,mBAAmB;6BAEtD,mBAAmB,KAAK,mBAAmB;CACnD,CAAC"}
1
+ {"version":3,"file":"geometry-engine.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/geometry-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,kBAAkB,CAAC;AAiB5E,iFAAiF;AACjF,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG;IAAE,MAAM,IAAI,OAAO,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAEpH,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjH,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,mBAAmB,GACnB,aAAa,GACb,cAAc,GACd,cAAc,GACd,OAAO,GACP,UAAU,CAAC;AA2Ef,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,YAA8B,GAAG,MAAM,CAKrG;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,YAA8B,GAAG,MAAM,CAInG;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,cAAyB,GAAG,MAAM,CAKlG;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,GAAE,cAAyB,GAAG,MAAM,CAIhG;AAwDD;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,cAAyB,GAC9B,YAAY,GAAG,IAAI,CAarB;AAED,gEAAgE;AAChE,wBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,YAAY,GAAG,IAAI,CAQjF;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAI3G;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAI3G;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAGxE;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAG1E;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAGxE;AAID,4FAA4F;AAC5F,wBAAgB,QAAQ,CAAC,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAE7F;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAElF;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;CAcvB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;6BACpB,mBAAmB,YAAY,MAAM,SAAS,cAAc;gCAEzD,mBAAmB,eAAe,mBAAmB;6BAExD,SAAS,mBAAmB,EAAE;iCAC1B,mBAAmB,cAAc,mBAAmB;mCAElD,mBAAmB,SAAS,YAAY;iCAC1C,mBAAmB,SAAS,YAAY;qCACpC,mBAAmB,SAAS,cAAc;mCAC5C,mBAAmB,SAAS,cAAc;+BAC9C,mBAAmB;iCACjB,mBAAmB;+BACrB,mBAAmB;mCACf,mBAAmB,UAAU,mBAAmB;6BAEtD,mBAAmB,KAAK,mBAAmB;CACnD,CAAC"}
@@ -25,7 +25,7 @@
25
25
  * @module
26
26
  */
27
27
  import { esriGeometryToGeoJSON, geoJsonToEsriGeometry } from "../core/esri-geojson.js";
28
- import { booleanContains, booleanIntersects, buffer as bufferOp, convex, difference as differenceOp, area as geodesicAreaOp, length as geodesicLengthOp, intersect as intersectOp, project, union as unionOp, } from "../geometry/index.js";
28
+ import { booleanContains, booleanIntersects, buffer as bufferOp, centroid as centroidOp, convex, difference as differenceOp, area as geodesicAreaOp, length as geodesicLengthOp, intersect as intersectOp, project, union as unionOp, } from "../geometry/index.js";
29
29
  const LINEAR_UNIT_METERS = {
30
30
  meters: 1,
31
31
  feet: 0.3048,
@@ -216,6 +216,11 @@ export function convexHull(input) {
216
216
  const { geometry, sr } = toGeoJson(input);
217
217
  return toEsri(convex(geometry), sr);
218
218
  }
219
+ /** Centroid of a geometry. Backed by `@turf/centroid`. */
220
+ export function centroid(input) {
221
+ const { geometry, sr } = toGeoJson(input);
222
+ return toEsri(centroidOp(geometry), sr);
223
+ }
219
224
  // ── Predicates ───────────────────────────────────────────────────
220
225
  /** True if `container` completely contains `inside`. Backed by `@turf/boolean-contains`. */
221
226
  export function contains(container, inside) {
@@ -242,6 +247,7 @@ export const geometryEngineCompat = {
242
247
  planarLength,
243
248
  simplify,
244
249
  convexHull,
250
+ centroid,
245
251
  contains,
246
252
  intersects,
247
253
  };
@@ -261,6 +267,7 @@ export const geometryEngineAsyncCompat = {
261
267
  planarLength: (input, unit) => Promise.resolve(planarLength(input, unit)),
262
268
  simplify: (input) => Promise.resolve(simplify(input)),
263
269
  convexHull: (input) => Promise.resolve(convexHull(input)),
270
+ centroid: (input) => Promise.resolve(centroid(input)),
264
271
  contains: (container, inside) => Promise.resolve(contains(container, inside)),
265
272
  intersects: (a, b) => Promise.resolve(intersects(a, b)),
266
273
  };
@@ -1,7 +1,10 @@
1
- /** Structural type for geometry-like objects (point, polyline, polygon, extent, etc.). */
2
- export type CompatGeometryLike = Record<string, unknown>;
3
- /** Structural type for symbol-like objects (marker, line, fill, text, etc.). */
4
- export type CompatSymbolLike = Record<string, unknown>;
1
+ /**
2
+ * Geometry passed to a graphic. Class instances such as `PointCompat` are
3
+ * values, so this is not an index signature (that would reject private fields).
4
+ */
5
+ export type CompatGeometryLike = object;
6
+ /** Symbol passed to a graphic. Class instances such as `SimpleMarkerSymbolCompat` are values. */
7
+ export type CompatSymbolLike = object;
5
8
  /** Structural type for popup template-like objects. */
6
9
  export type CompatPopupTemplateLike = Record<string, unknown>;
7
10
  export interface GraphicCompatOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"graphic.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/graphic.ts"],"names":[],"mappings":"AAEA,0FAA0F;AAC1F,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzD,gFAAgF;AAChF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvD,uDAAuD;AACvD,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,aAAa;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,uBAAuB,CAAC;IACpC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,aAAa,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;gBAEzD,OAAO,GAAE,oBAAyB;IAWxC,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IAc9B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ/E,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,mBAAmB;IACtF,KAAK,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GAAG,mBAAmB;IACtG,KAAK,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,mBAAmB;IAgBpF,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAKtD,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAKhD,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAKxD,gBAAgB,CAAC,aAAa,EAAE,uBAAuB,GAAG,IAAI,GAAG,IAAI;IAKrE,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK9B,KAAK,IAAI,aAAa;IAUtB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUjC,OAAO,IAAI,IAAI;IAItB,OAAO,CAAC,cAAc;CAUvB"}
1
+ {"version":3,"file":"graphic.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/graphic.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC,uDAAuD;AACvD,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,aAAa;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,uBAAuB,CAAC;IACpC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,aAAa,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC9C,KAAK,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;gBAEzD,OAAO,GAAE,oBAAyB;IAWxC,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IAc9B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ/E,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,mBAAmB;IACtF,KAAK,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GAAG,mBAAmB;IACtG,KAAK,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,mBAAmB;IAC1G,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,mBAAmB;IAgBpF,WAAW,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAKtD,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAKhD,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAKxD,gBAAgB,CAAC,aAAa,EAAE,uBAAuB,GAAG,IAAI,GAAG,IAAI;IAKrE,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK9B,KAAK,IAAI,aAAa;IAUtB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUjC,OAAO,IAAI,IAAI;IAItB,OAAO,CAAC,cAAc;CAUvB"}
@@ -29,7 +29,7 @@ export interface LegendHandleCompat {
29
29
  export declare class LegendCompat {
30
30
  readonly view: unknown;
31
31
  readonly map: unknown;
32
- readonly container: unknown;
32
+ container: unknown;
33
33
  readonly eventBus: CompatEventBus;
34
34
  readonly includeHidden: boolean;
35
35
  loaded: boolean;
@@ -53,6 +53,7 @@ export declare class LegendCompat {
53
53
  when(callback?: (widget: LegendCompat) => void): Promise<LegendCompat>;
54
54
  watch(propertyName: string, listener: (value: unknown) => void): LegendHandleCompat;
55
55
  refresh(): Promise<readonly LegendLayerGroupCompat[]>;
56
+ attachContainer(element: HTMLElement): void;
56
57
  destroy(): void;
57
58
  /** Pushes the current items into the delegated `<honua-legend>` element. */
58
59
  private renderWidgetHost;
@@ -1 +1 @@
1
- {"version":3,"file":"legend.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/legend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAIf,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,SAAgB,IAAI,EAAE,OAAO,CAAC;IAC9B,SAAgB,GAAG,EAAE,OAAO,CAAC;IAC7B,SAAgB,SAAS,EAAE,OAAO,CAAC;IACnC,SAAgB,QAAQ,EAAE,cAAc,CAAC;IACzC,SAAgB,aAAa,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,sBAAsB,CAAC;IACnC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAEvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;IAC5E,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,eAAe,CAAS;IAChC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;gBAEtC,OAAO,GAAE,mBAAwB;IAkCvC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAiB7B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ5E,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,kBAAkB;IAe7E,OAAO,IAAI,OAAO,CAAC,SAAS,sBAAsB,EAAE,CAAC;IAqC3D,OAAO,IAAI,IAAI;IAQtB,4EAA4E;YAC9D,gBAAgB;IAe9B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;CAUvB"}
1
+ {"version":3,"file":"legend.d.ts","sourceRoot":"","sources":["../../../src/esri-compat/legend.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAIf,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,qBAAa,YAAY;IACvB,SAAgB,IAAI,EAAE,OAAO,CAAC;IAC9B,SAAgB,GAAG,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IAC1B,SAAgB,QAAQ,EAAE,cAAc,CAAC;IACzC,SAAgB,aAAa,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,sBAAsB,CAAC;IACnC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAEvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;IAC5E,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,eAAe,CAAS;IAChC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;gBAEtC,OAAO,GAAE,mBAAwB;IAyCvC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAC;IAiB7B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;IAQ5E,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,kBAAkB;IAe7E,OAAO,IAAI,OAAO,CAAC,SAAS,sBAAsB,EAAE,CAAC;IAqC3D,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAS3C,OAAO,IAAI,IAAI;IAQtB,4EAA4E;YAC9D,gBAAgB;IAe9B,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;CAUvB"}
@@ -52,6 +52,13 @@ export class LegendCompat {
52
52
  this.subscriptions.push(this.eventBus.on("layer.visibility-changed", () => void this.refresh()));
53
53
  this.subscriptions.push(this.eventBus.on("layer.legend-updated", () => void this.refresh()));
54
54
  }
55
+ if (typeof HTMLElement !== "undefined" && this.container instanceof HTMLElement) {
56
+ queueMicrotask(() => {
57
+ if (this.loadStatus === "not-loaded") {
58
+ void this.load();
59
+ }
60
+ });
61
+ }
55
62
  }
56
63
  async load() {
57
64
  if (this.loaded) {
@@ -122,6 +129,14 @@ export class LegendCompat {
122
129
  void this.renderWidgetHost();
123
130
  return this.items;
124
131
  }
132
+ attachContainer(element) {
133
+ this.container = element;
134
+ if (this.loaded) {
135
+ void this.renderWidgetHost();
136
+ return;
137
+ }
138
+ void this.load();
139
+ }
125
140
  destroy() {
126
141
  for (const subscription of this.subscriptions.splice(0)) {
127
142
  subscription.remove();