@honua/sdk-esri-compat 0.1.17 → 0.1.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/contract/source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/contract/source.ts"],"names":[],"mappings":"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"}
@@ -230,7 +230,10 @@ export function geoServicesFeatureSource(descriptor, client, policy) {
230
230
  // set rather than silently inheriting REST-only capabilities (`pbf`,
231
231
  // `sql`, `attachments`, `queryRelated`) the gRPC FeatureService RPC
232
232
  // surface does not support.
233
- const caps = descriptor.capabilities ?? PROTOCOL_DEFAULT_CAPABILITIES[descriptor.protocol];
233
+ const declaredCaps = descriptor.capabilities ?? PROTOCOL_DEFAULT_CAPABILITIES[descriptor.protocol];
234
+ const caps = client.isGrpcWeb
235
+ ? new Set([...declaredCaps].filter((capability) => PROTOCOL_DEFAULT_CAPABILITIES.grpc.has(capability)))
236
+ : declaredCaps;
234
237
  const adapterRegistry = {
235
238
  "geoservices-feature-service": layer,
236
239
  };
@@ -258,6 +261,13 @@ export function geoServicesFeatureSource(descriptor, client, policy) {
258
261
  };
259
262
  },
260
263
  async queryAggregate(request) {
264
+ if (client.isGrpcWeb) {
265
+ if (policy === "strict") {
266
+ throw new HonuaCapabilityNotSupportedError("queryAggregate", "grpc", descriptor.id);
267
+ }
268
+ ensureCapability(descriptor, caps, "query");
269
+ return grpcMaterializedAggregate(layer, request, descriptor);
270
+ }
261
271
  ensureCapability(descriptor, caps, "queryAggregate");
262
272
  const requestParams = toFeatureLayerRequest(request, descriptor);
263
273
  const { aggregateAlias, ...aggFields } = buildAggregationFields(request.aggregation);
@@ -266,8 +276,13 @@ export function geoServicesFeatureSource(descriptor, client, policy) {
266
276
  },
267
277
  async queryExtent(request) {
268
278
  ensureCapability(descriptor, caps, "queryExtent");
269
- const response = await layer.queryFeatures(toExtentOnlyRequest(toFeatureLayerRequest(request, descriptor)));
270
- return extractExtentEnvelope(response);
279
+ const params = toExtentOnlyRequest(toFeatureLayerRequest(request, descriptor));
280
+ const response = await layer.queryFeatures(params);
281
+ const envelope = extractExtentEnvelope(response);
282
+ if (client.isGrpcWeb && envelope.count === undefined) {
283
+ return { ...envelope, count: await grpcExactCount(layer, params, descriptor) };
284
+ }
285
+ return envelope;
271
286
  },
272
287
  async *stream(request) {
273
288
  ensureCapability(descriptor, caps, "stream");
@@ -4033,6 +4048,176 @@ function aggregateResultFromUntyped(response, _alias) {
4033
4048
  fields: response.fields,
4034
4049
  };
4035
4050
  }
4051
+ async function grpcExactCount(layer, params, descriptor) {
4052
+ const { resultOffset: _offset, resultRecordCount: _limit, outFields: _fields, ...rest } = params;
4053
+ void _offset;
4054
+ void _limit;
4055
+ void _fields;
4056
+ const { returnExtentOnly: _extent, ...extraParams } = rest.extraParams ?? {};
4057
+ void _extent;
4058
+ const response = await layer.client.queryFeatures({
4059
+ serviceId: layer.serviceId,
4060
+ layerId: layer.layerId,
4061
+ ...rest,
4062
+ returnGeometry: false,
4063
+ extraParams: { ...extraParams, returnCountOnly: true },
4064
+ });
4065
+ const count = typeof response === "object" && response !== null ? response.count : undefined;
4066
+ if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0) {
4067
+ throw new HonuaCapabilityNotSupportedError("count", "grpc", descriptor.id, {
4068
+ context: { reason: "gRPC count response did not contain an exact nonnegative count." },
4069
+ });
4070
+ }
4071
+ return count;
4072
+ }
4073
+ function grpcAggregateError(sourceId, context) {
4074
+ return new HonuaCapabilityNotSupportedError("queryAggregate", "grpc", sourceId, { context });
4075
+ }
4076
+ async function grpcMaterializedAggregate(layer, request, descriptor) {
4077
+ if (request.aggregation.histogram || request.aggregation.timeSeries) {
4078
+ throw grpcAggregateError(descriptor.id);
4079
+ }
4080
+ if (request.aggregation.groupBy?.includes("*") ||
4081
+ request.aggregation.metrics.some((metric) => metric.field === "*" && metric.fn !== "count")) {
4082
+ throw grpcAggregateError(descriptor.id, { reason: "Wildcard fields are supported only for COUNT(*)." });
4083
+ }
4084
+ // Aggregate the whole matching set, independently of the caller's display
4085
+ // window. Never return a partial aggregate when the finite drain budget ends.
4086
+ const params = toFeatureLayerRequest({ ...request, pagination: undefined }, descriptor);
4087
+ const expectedCount = await grpcExactCount(layer, params, descriptor);
4088
+ const pageSize = 2000;
4089
+ const maxPages = 100;
4090
+ if (expectedCount > pageSize * maxPages) {
4091
+ throw grpcAggregateError(descriptor.id, {
4092
+ reason: "Matching set exceeds the 200000-feature client-side aggregation budget.",
4093
+ expectedCount,
4094
+ });
4095
+ }
4096
+ const features = [];
4097
+ const ids = new Set();
4098
+ for (let page = 0; page < maxPages && (page === 0 || features.length < expectedCount); page += 1) {
4099
+ const response = await layer.queryFeatures({
4100
+ ...params,
4101
+ outFields: ["*"],
4102
+ returnGeometry: false,
4103
+ resultOffset: features.length,
4104
+ resultRecordCount: pageSize,
4105
+ });
4106
+ const requiredFields = [
4107
+ ...(request.aggregation.groupBy ?? []),
4108
+ ...request.aggregation.metrics.map((metric) => metric.field),
4109
+ ].filter((field) => field !== "*");
4110
+ for (const field of requiredFields) {
4111
+ if (response.fields?.filter((definition) => definition.name.toLowerCase() === field.toLowerCase()).length !== 1) {
4112
+ throw grpcAggregateError(descriptor.id, {
4113
+ reason: "Aggregate field is unknown or ambiguous in the server field schema.",
4114
+ field,
4115
+ });
4116
+ }
4117
+ }
4118
+ const rows = response.features ?? [];
4119
+ if (rows.length > pageSize) {
4120
+ throw grpcAggregateError(descriptor.id, {
4121
+ reason: "gRPC response exceeded the requested materialization page budget.",
4122
+ });
4123
+ }
4124
+ if (rows.length === 0)
4125
+ break;
4126
+ for (const feature of rows) {
4127
+ const id = response.objectIdFieldName
4128
+ ? grpcAggregateField(feature.attributes, response.objectIdFieldName)
4129
+ : undefined;
4130
+ if ((typeof id !== "number" && typeof id !== "string") ||
4131
+ (typeof id === "number" && !Number.isSafeInteger(id)) ||
4132
+ id === "" ||
4133
+ ids.has(String(id))) {
4134
+ throw grpcAggregateError(descriptor.id, {
4135
+ reason: "gRPC materialization returned a missing or repeated object ID; no aggregate was returned.",
4136
+ });
4137
+ }
4138
+ ids.add(String(id));
4139
+ }
4140
+ features.push(...rows);
4141
+ if (features.length > expectedCount || (!response.exceededTransferLimit && rows.length < pageSize))
4142
+ break;
4143
+ }
4144
+ if (features.length !== expectedCount) {
4145
+ throw grpcAggregateError(descriptor.id, {
4146
+ reason: "gRPC materialization did not match the exact count; no partial aggregate was returned.",
4147
+ expectedCount,
4148
+ actualCount: features.length,
4149
+ });
4150
+ }
4151
+ return {
4152
+ features,
4153
+ exceededTransferLimit: false,
4154
+ totalCount: expectedCount,
4155
+ aggregateRows: grpcAggregateRows(features, request.aggregation),
4156
+ degraded: [
4157
+ {
4158
+ capability: "queryAggregate",
4159
+ reason: "gRPC does not expose server-side aggregation; evaluated client-side over the complete matching set.",
4160
+ protocol: "grpc",
4161
+ sourceId: descriptor.id,
4162
+ },
4163
+ ],
4164
+ };
4165
+ }
4166
+ // SQL field aggregates count non-null field values, use null for an empty
4167
+ // numeric input, and use sample variance like the canonical Postgres provider.
4168
+ // Keep this transport fallback separate from existing OGC page evaluation.
4169
+ function grpcAggregateField(attributes, field) {
4170
+ if (typeof attributes !== "object" || attributes === null)
4171
+ return undefined;
4172
+ const key = Object.keys(attributes).find((key) => key.toLowerCase() === field.toLowerCase());
4173
+ return key === undefined ? undefined : attributes[key];
4174
+ }
4175
+ function grpcAggregateRows(features, aggregation) {
4176
+ const groups = new Map();
4177
+ const groupFields = aggregation.groupBy ?? [];
4178
+ if (groupFields.length === 0)
4179
+ groups.set("[]", { keys: [], rows: [] });
4180
+ for (const feature of features) {
4181
+ const keys = groupFields.map((field) => grpcAggregateField(feature.attributes, field) ?? null);
4182
+ const key = JSON.stringify(keys);
4183
+ let group = groups.get(key);
4184
+ if (!group) {
4185
+ group = { keys, rows: [] };
4186
+ groups.set(key, group);
4187
+ }
4188
+ group.rows.push(feature);
4189
+ }
4190
+ return Array.from(groups.values(), ({ keys, rows }) => {
4191
+ const output = Object.fromEntries(groupFields.map((field, i) => [field, keys[i]]));
4192
+ for (const metric of aggregation.metrics) {
4193
+ const values = rows
4194
+ .map((row) => grpcAggregateField(row.attributes, metric.field))
4195
+ .filter((value) => value != null);
4196
+ const alias = metric.alias ?? `${metric.fn}_${metric.field}`;
4197
+ if (metric.fn === "count") {
4198
+ output[alias] = metric.field === "*" ? rows.length : values.length;
4199
+ continue;
4200
+ }
4201
+ if (values.some((value) => !Number.isFinite(value))) {
4202
+ throw grpcAggregateError(undefined, {
4203
+ reason: "Numeric client-side aggregation requires finite numeric field values.",
4204
+ });
4205
+ }
4206
+ const numbers = values;
4207
+ if (numbers.length === 0 || ((metric.fn === "stddev" || metric.fn === "var") && numbers.length < 2)) {
4208
+ output[alias] = null;
4209
+ continue;
4210
+ }
4211
+ output[alias] = applyAggregation(metric.fn, numbers, rows.length, true);
4212
+ if (typeof output[alias] === "number" && !Number.isFinite(output[alias])) {
4213
+ throw grpcAggregateError(undefined, {
4214
+ reason: "Client-side aggregation overflowed; no nonfinite aggregate was returned.",
4215
+ });
4216
+ }
4217
+ }
4218
+ return output;
4219
+ });
4220
+ }
4036
4221
  function clientSideAggregate(features, aggregation) {
4037
4222
  const groupKeys = aggregation.groupBy ?? [];
4038
4223
  if (groupKeys.length === 0) {
@@ -4071,7 +4256,7 @@ function computeMetrics(features, metrics) {
4071
4256
  }
4072
4257
  return out;
4073
4258
  }
4074
- function applyAggregation(fn, values, totalLength) {
4259
+ function applyAggregation(fn, values, totalLength, sampleVariance = false) {
4075
4260
  if (fn === "count")
4076
4261
  return totalLength;
4077
4262
  if (values.length === 0)
@@ -4082,13 +4267,13 @@ function applyAggregation(fn, values, totalLength) {
4082
4267
  case "avg":
4083
4268
  return values.reduce((a, b) => a + b, 0) / values.length;
4084
4269
  case "min":
4085
- return Math.min(...values);
4270
+ return values.reduce((a, b) => Math.min(a, b));
4086
4271
  case "max":
4087
- return Math.max(...values);
4272
+ return values.reduce((a, b) => Math.max(a, b));
4088
4273
  case "stddev":
4089
4274
  case "var": {
4090
4275
  const mean = values.reduce((a, b) => a + b, 0) / values.length;
4091
- const variance = values.reduce((a, b) => a + (b - mean) ** 2, 0) / values.length;
4276
+ const variance = values.reduce((a, b) => a + (b - mean) ** 2, 0) / (values.length - (sampleVariance ? 1 : 0));
4092
4277
  return fn === "var" ? variance : Math.sqrt(variance);
4093
4278
  }
4094
4279
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honua/sdk-esri-compat",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "ArcGIS JS API compatibility layer for ArcGIS migration from Esri apps to the open Honua + MapLibre stack",
5
5
  "keywords": [
6
6
  "gis",
@@ -46,7 +46,7 @@
46
46
  "proj4": "^2.20.9"
47
47
  },
48
48
  "peerDependencies": {
49
- "@honua/sdk": "0.1.17",
49
+ "@honua/sdk": "0.1.18",
50
50
  "@bufbuild/protobuf": "^2.0.0",
51
51
  "@connectrpc/connect": "^2.0.0",
52
52
  "@connectrpc/connect-web": "^2.0.0",