@flighthq/spatial 0.3.0-next.1392.f0bd0cc → 0.3.0-next.1422.b585c0c

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":"explainSpatialIndexing.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAW1G,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,0BAA0B,CAErH"}
1
+ {"version":3,"file":"explainSpatialIndexing.d.ts","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAY1G,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,eAAe,GAAG,0BAA0B,CAErH"}
@@ -1,8 +1,9 @@
1
1
  // Reports how the index is currently holding `id`, as plain data. Pure: reads only, indexes nothing,
2
2
  // never throws on an unknown id, and retains no reference to the backend. Import it to answer "why is
3
3
  // this object not in my query results?" — `absent` means it was never inserted or was removed,
4
- // `declined` means its bounds were non-finite and it is deliberately not held, `overflow` means it is
5
- // held but too large to bucket, and `cells` reports the bucket count the per-object bound caps.
4
+ // `declined` means its bounds were non-finite or inverted and it is deliberately not held, `overflow`
5
+ // means it is held but cannot be usefully bucketed, and `cells` reports the bucket count the
6
+ // per-object bound caps.
6
7
  //
7
8
  // This is the pull half of the diagnostics convention, and the measurement seam a regression test
8
9
  // asserts the cost bound against: `bucketCount` is the number that goes unbounded when the bound is
@@ -1 +1 @@
1
- {"version":3,"file":"explainSpatialIndexing.js","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,gGAAgG;AAChG,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AACpG,yDAAyD;AACzD,MAAM,UAAU,sBAAsB,CAAC,KAA6B,EAAE,EAAmB;IACvF,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"explainSpatialIndexing.js","sourceRoot":"","sources":["../src/explainSpatialIndexing.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,sGAAsG;AACtG,+FAA+F;AAC/F,sGAAsG;AACtG,6FAA6F;AAC7F,yBAAyB;AACzB,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AACpG,yDAAyD;AACzD,MAAM,UAAU,sBAAsB,CAAC,KAA6B,EAAE,EAAmB;IACvF,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AActE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAU3F"}
1
+ {"version":3,"file":"formatSpatialIndexingNotice.d.ts","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AActE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAsB3F"}
@@ -10,14 +10,26 @@ import { MAX_INDEXED_CELLS_PER_OBJECT } from './uniformGrid';
10
10
  //
11
11
  // setSpatialIndexingGuard((notice) => logWarn({ message: formatSpatialIndexingNotice(notice) }, 'spatial'));
12
12
  export function formatSpatialIndexingNotice(notice) {
13
+ if (notice.reason === 'invalid-cell-size') {
14
+ return `createUniformGridSpatialBackend(${notice.cellSize}): cellSize must be a positive finite number. ${notice.operation}SpatialObject(${notice.id}) used the bounded overflow path instead, so results remain correct but queries scan this object.`;
15
+ }
16
+ if (notice.reason === 'inverted-bounds') {
17
+ return `${notice.operation}SpatialObject(${notice.id}): minX/minY must not exceed maxX/maxY, so the object was not indexed and no query will return it. The operation returns false for this — normalize or correct the bounds upstream.`;
18
+ }
19
+ if (notice.reason === 'missing-id') {
20
+ if (notice.operation === 'remove') {
21
+ return `removeSpatialObject(${notice.id}): the id was not indexed, so removal was a no-op. Check the object's indexing lifecycle if this was unexpected.`;
22
+ }
23
+ return `updateSpatialObject(${notice.id}): the id was not indexed, so update used its documented insert behavior and left the object in '${notice.mode}' mode. Use insertSpatialObject for a new id, or check the object's indexing lifecycle.`;
24
+ }
13
25
  if (notice.mode === 'declined') {
14
- return `insertSpatialObject(${notice.id}): the bounds are not finite, so the object was not indexed and no query will return it. Insert returns false for this — check the sentinel, and check what produced NaN/Infinity bounds upstream.`;
26
+ return `${notice.operation}SpatialObject(${notice.id}): the bounds are not finite, so the object was not indexed and no query will return it. The operation returns false for this — check the sentinel, and check what produced NaN/Infinity bounds upstream.`;
15
27
  }
16
28
  if (notice.mode === 'overflow') {
17
- return `insertSpatialObject(${notice.id}): the bounds span ${notice.wouldOccupyBucketCount} cells, over the ${MAX_INDEXED_CELLS_PER_OBJECT} per-object budget, so the object is held in the flat overflow list instead of the grid. Results are unaffected. If this is not a one-off outlier, the grid's cellSize is too small for the objects being indexed — size it to a typical object.`;
29
+ return `${notice.operation}SpatialObject(${notice.id}): the bounds span ${notice.wouldOccupyBucketCount} cells, over the ${MAX_INDEXED_CELLS_PER_OBJECT} per-object budget, so the object is held in the flat overflow list instead of the grid. Results are unaffected. If this is not a one-off outlier, the grid's cellSize is too small for the objects being indexed — size it to a typical object.`;
18
30
  }
19
31
  // `cells` and `absent` are ordinary outcomes no guard reports, so reaching here means a backend
20
32
  // notified about something this text does not cover. Say exactly that rather than inventing advice.
21
- return `insertSpatialObject(${notice.id}): indexed as '${notice.mode}', which carries no caller-facing advice.`;
33
+ return `${notice.operation}SpatialObject(${notice.id}): indexed as '${notice.mode}', which carries no caller-facing advice.`;
22
34
  }
23
35
  //# sourceMappingURL=formatSpatialIndexingNotice.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,4FAA4F;AAC5F,qGAAqG;AACrG,sGAAsG;AACtG,gGAAgG;AAChG,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,uBAAuB,MAAM,CAAC,EAAE,oMAAoM,CAAC;IAC9O,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,uBAAuB,MAAM,CAAC,EAAE,sBAAsB,MAAM,CAAC,sBAAsB,oBAAoB,4BAA4B,kPAAkP,CAAC;IAC/X,CAAC;IACD,gGAAgG;IAChG,oGAAoG;IACpG,OAAO,uBAAuB,MAAM,CAAC,EAAE,kBAAkB,MAAM,CAAC,IAAI,2CAA2C,CAAC;AAClH,CAAC"}
1
+ {"version":3,"file":"formatSpatialIndexingNotice.js","sourceRoot":"","sources":["../src/formatSpatialIndexingNotice.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D,qGAAqG;AACrG,sGAAsG;AACtG,2FAA2F;AAC3F,EAAE;AACF,4FAA4F;AAC5F,qGAAqG;AACrG,sGAAsG;AACtG,gGAAgG;AAChG,EAAE;AACF,+GAA+G;AAC/G,MAAM,UAAU,2BAA2B,CAAC,MAAuC;IACjF,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;QAC1C,OAAO,mCAAmC,MAAM,CAAC,QAAQ,iDAAiD,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,mGAAmG,CAAC;IAC1P,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACxC,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,qLAAqL,CAAC;IAC5O,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,uBAAuB,MAAM,CAAC,EAAE,kHAAkH,CAAC;QAC5J,CAAC;QACD,OAAO,uBAAuB,MAAM,CAAC,EAAE,oGAAoG,MAAM,CAAC,IAAI,yFAAyF,CAAC;IAClP,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,2MAA2M,CAAC;IAClQ,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,sBAAsB,MAAM,CAAC,sBAAsB,oBAAoB,4BAA4B,kPAAkP,CAAC;IAC5Y,CAAC;IACD,gGAAgG;IAChG,oGAAoG;IACpG,OAAO,GAAG,MAAM,CAAC,SAAS,iBAAiB,MAAM,CAAC,EAAE,kBAAkB,MAAM,CAAC,IAAI,2CAA2C,CAAC;AAC/H,CAAC"}
@@ -16,9 +16,9 @@ export function createSpatialIndex(backend) {
16
16
  }
17
17
  // Adds an object to the index under `id` with its current bounds. The bounds are copied; the caller
18
18
  // may reuse its own value afterward. Returns false when the bounds cannot be indexed at all
19
- // (non-finite) — the object is then absent from every query rather than present at a nonsense
20
- // position. Oversized-but-finite bounds return true and stay fully queryable; the backend decides how
21
- // to hold them. explainSpatialIndexing reports which happened.
19
+ // (non-finite or inverted) — the object is then absent from every query rather than present at a
20
+ // nonsense position. Oversized-but-valid bounds return true and stay fully queryable; the backend
21
+ // decides how to hold them. explainSpatialIndexing reports which happened.
22
22
  export function insertSpatialObject(index, id, bounds) {
23
23
  return index.runtime.backend.insertSpatialObject(id, bounds);
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEhE,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,+BAA+B,CAAC,yBAAyB,CAAC;SAC/E;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,8FAA8F;AAC9F,sGAAsG;AACtG,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,GAAkB;IACjF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,CAAS,EAAE,CAAS,EAAE,GAAsB;IAC3G,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,UAAU,eAAe,CAC7B,KAA6B,EAC7B,CAAS,EACT,CAAS,EACT,EAAU,EACV,EAAU,EACV,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAChC,KAA6B,EAC7B,MAA6B,EAC7B,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,KAA6B,EAAE,EAAmB;IACpF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,qGAAqG;AACrG,sGAAsG;AACtG,oBAAoB;AACpB,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"spatialIndex.js","sourceRoot":"","sources":["../src/spatialIndex.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEhE,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;AAC5C,CAAC;AAED,yFAAyF;AACzF,kGAAkG;AAClG,mGAAmG;AACnG,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAAC,OAA6B;IAC9D,OAAO;QACL,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,IAAI,+BAA+B,CAAC,yBAAyB,CAAC;SAC/E;KACF,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,4FAA4F;AAC5F,iGAAiG;AACjG,kGAAkG;AAClG,2EAA2E;AAC3E,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,mGAAmG;AACnG,iGAAiG;AACjG,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,GAAkB;IACjF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAA6B,EAAE,CAAS,EAAE,CAAS,EAAE,GAAsB;IAC3G,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,kGAAkG;AAClG,MAAM,UAAU,eAAe,CAC7B,KAA6B,EAC7B,CAAS,EACT,CAAS,EACT,EAAU,EACV,EAAU,EACV,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAChC,KAA6B,EAC7B,MAA6B,EAC7B,GAAsB;IAEtB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,mBAAmB,CAAC,KAA6B,EAAE,EAAmB;IACpF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,qGAAqG;AACrG,sGAAsG;AACtG,oBAAoB;AACpB,MAAM,UAAU,mBAAmB,CACjC,KAA6B,EAC7B,EAAmB,EACnB,MAA6B;IAE7B,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,qGAAqG;AACrG,MAAM,yBAAyB,GAAG,GAAG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,EAEnB,oBAAoB,EAGrB,MAAM,0BAA0B,CAAC;AAiBlC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAajD,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CA8CrF;AAOD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAEhF"}
1
+ {"version":3,"file":"uniformGrid.d.ts","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,mBAAmB,EAGnB,oBAAoB,EAMrB,MAAM,0BAA0B,CAAC;AAiBlC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAejD,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAkDrF;AAKD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAEhF"}
@@ -13,41 +13,47 @@ import { containsRectanglePointXY, intersectsRectangle } from '@flighthq/geometr
13
13
  // everything, so the cell index tells the queries almost nothing and a linear scan answers the same
14
14
  // question at a bounded cost. 1024 cells is a 32×32 block — an object 32× the cell size on each axis,
15
15
  // far past the "cell size ≈ typical object size" the grid is built around. An object over the budget
16
- // is a signal the cell size is wrong for the workload, which is what enableSpatialGuards reports.
16
+ // is a signal the cell size is wrong for the workload, which the indexing guard reports.
17
17
  export const MAX_INDEXED_CELLS_PER_OBJECT = 1024;
18
18
  // Builds a uniform-grid (spatial-hash) backend: an object's AABB is mapped to the rectangular block
19
19
  // of fixed-size cells it covers, and each cell holds the ids overlapping it. Co-located objects share
20
20
  // a cell, so candidate pairs and region/point/ray hits are found by looking only at the relevant
21
21
  // cells instead of scanning every object. `cellSize` is the world-space side length of one cell; a
22
- // good value is roughly the size of a typical object (too small over-spans large objects across many
23
- // cells, too large lumps unrelated objects together). No import-time side effect — the caller
24
- // constructs a grid explicitly, and createSpatialIndex uses this as its default index.
22
+ // good value is a positive finite number roughly the size of a typical object (too small over-spans
23
+ // large objects across many cells, too large lumps unrelated objects together). An invalid size uses
24
+ // the bounded overflow path to keep results correct and reports through the indexing guard. No
25
+ // import-time side effect — the caller constructs a grid explicitly, and createSpatialIndex uses
26
+ // this as its default index.
25
27
  //
26
28
  // Object size does not set the cost: an AABB spanning more than MAX_INDEXED_CELLS_PER_OBJECT cells
27
- // goes to a flat overflow list that every query scans, and non-finite bounds are declined outright
28
- // with a false sentinel. Both are visible through explainSpatialIndexing.
29
+ // goes to a flat overflow list that every query scans, and non-finite or inverted bounds are declined
30
+ // outright with a false sentinel. Both are visible through explainSpatialIndexing.
29
31
  export function createUniformGridSpatialBackend(cellSize) {
30
32
  const grid = {
31
33
  cellSize,
32
34
  cells: new Map(),
33
35
  bounds: new Map(),
34
36
  overflow: new Set(),
35
- declined: new Set(),
37
+ declined: new Map(),
36
38
  minCellX: 0,
37
39
  minCellY: 0,
38
40
  maxCellX: 0,
39
41
  maxCellY: 0,
40
42
  seen: new Set(),
43
+ pairIds: [],
41
44
  };
42
45
  return {
43
46
  insertSpatialObject(id, bounds) {
44
- return _insertIntoGrid(grid, id, bounds);
47
+ return _insertIntoGrid(grid, id, bounds, 'insert');
45
48
  },
46
49
  updateSpatialObject(id, bounds) {
47
50
  return _updateGridObject(grid, id, bounds);
48
51
  },
49
52
  removeSpatialObject(id) {
53
+ const wasMissing = !grid.bounds.has(id) && !grid.declined.has(id);
50
54
  _removeFromGrid(grid, id);
55
+ if (wasMissing)
56
+ _reportGridIndexing(grid, id, 'absent', 'remove', 'missing-id', 0);
51
57
  },
52
58
  clearSpatialIndex() {
53
59
  grid.cells.clear();
@@ -55,6 +61,7 @@ export function createUniformGridSpatialBackend(cellSize) {
55
61
  grid.overflow.clear();
56
62
  grid.declined.clear();
57
63
  grid.seen.clear();
64
+ grid.pairIds.length = 0;
58
65
  },
59
66
  explainSpatialIndexing(id) {
60
67
  return _explainGridIndexing(grid, id);
@@ -73,11 +80,9 @@ export function createUniformGridSpatialBackend(cellSize) {
73
80
  },
74
81
  };
75
82
  }
76
- // Installs the indexing guard consulted whenever an object is declined or routed to overflow; null
77
- // uninstalls it. This is the diagnostics seam, not the caller-facing entry point — use
78
- // enableSpatialGuards, which installs the @flighthq/log reporter through here. Module-scoped rather
79
- // than per-grid: it is a development diagnostic, and an application debugging a missing object wants
80
- // it on for every index at once.
83
+ // Installs the indexing guard consulted for invalid configuration or bounds, missing-id operations,
84
+ // and overflow routing; null uninstalls it. Module-scoped rather than per-grid: it is a development
85
+ // diagnostic, and an application debugging an index wants it on for every grid at once.
81
86
  export function setSpatialIndexingGuard(guard) {
82
87
  _indexingGuard = guard;
83
88
  }
@@ -93,8 +98,7 @@ function _cellKey(cx, cy) {
93
98
  }
94
99
  // Fills a scratch RectangleLike (x/y/width/height) from a SpatialAabb (min/max corners) so the
95
100
  // geometry rectangle-overlap and point-containment helpers can be reused instead of re-deriving the
96
- // AABB math here. Assumes a normalized AABB (max >= min); a flipped AABB yields a negative extent,
97
- // which the geometry helpers still normalize internally.
101
+ // AABB math here. Stored AABBs are normalized because insert declines inverted bounds.
98
102
  function _fillRectFromAabb(out, aabb) {
99
103
  out.x = aabb.minX;
100
104
  out.y = aabb.minY;
@@ -103,8 +107,9 @@ function _fillRectFromAabb(out, aabb) {
103
107
  }
104
108
  // Reports how `id` is currently held. Pure: reads only, allocates only the returned record.
105
109
  function _explainGridIndexing(grid, id) {
106
- if (grid.declined.has(id))
107
- return { bucketCount: 0, id, mode: 'declined', reason: 'non-finite-bounds' };
110
+ const declineReason = grid.declined.get(id);
111
+ if (declineReason !== undefined)
112
+ return { bucketCount: 0, id, mode: 'declined', reason: declineReason };
108
113
  if (grid.overflow.has(id))
109
114
  return { bucketCount: 0, id, mode: 'overflow', reason: null };
110
115
  const bounds = grid.bounds.get(id);
@@ -115,38 +120,47 @@ function _explainGridIndexing(grid, id) {
115
120
  // Adds an object to the index, storing a private copy of the bounds; the caller may safely mutate or
116
121
  // reuse the passed bounds afterward. Returns false only for bounds that cannot be indexed at all.
117
122
  //
118
- // Three outcomes, and which one applies is decided *before* any cell is touched — that ordering is
123
+ // Five outcomes, and which one applies is decided *before* any cell is touched — that ordering is
119
124
  // the whole point, since deciding afterward would mean walking the cells to find out they were too
120
125
  // many:
121
126
  // - non-finite bounds are declined. There is no cell range to compute, and storing them would let a
122
127
  // NaN leak into every later overlap test, so the object is left out of the index entirely and the
123
128
  // caller gets a false sentinel rather than an exception or a silent no-op.
129
+ // - inverted bounds are likewise declined because min/max corners do not describe an AABB.
130
+ // - a non-positive or non-finite cell size routes valid objects to overflow, preserving query
131
+ // correctness through the bounded flat scan while the indexing guard reports the configuration.
124
132
  // - bounds spanning more than MAX_INDEXED_CELLS_PER_OBJECT cells go to the overflow list, which
125
133
  // every query scans. Bounded by the object count instead of the object's size.
126
134
  // - everything else takes the ordinary path: one entry in each cell it covers.
127
- function _insertIntoGrid(grid, id, bounds) {
135
+ function _insertIntoGrid(grid, id, bounds, operation) {
128
136
  if (!Number.isFinite(bounds.minX) ||
129
137
  !Number.isFinite(bounds.minY) ||
130
138
  !Number.isFinite(bounds.maxX) ||
131
139
  !Number.isFinite(bounds.maxY)) {
132
- grid.declined.add(id);
133
- if (_indexingGuard !== null) {
134
- _indexingGuard({ id, mode: 'declined', reason: 'non-finite-bounds', wouldOccupyBucketCount: 0 });
135
- }
140
+ grid.declined.set(id, 'non-finite-bounds');
141
+ _reportGridIndexing(grid, id, 'declined', operation, 'non-finite-bounds', 0);
142
+ return false;
143
+ }
144
+ if (bounds.maxX < bounds.minX || bounds.maxY < bounds.minY) {
145
+ grid.declined.set(id, 'inverted-bounds');
146
+ _reportGridIndexing(grid, id, 'declined', operation, 'inverted-bounds', 0);
136
147
  return false;
137
148
  }
138
149
  const cs = grid.cellSize;
139
150
  const copy = { minX: bounds.minX, minY: bounds.minY, maxX: bounds.maxX, maxY: bounds.maxY };
151
+ if (!(cs > 0 && Number.isFinite(cs))) {
152
+ grid.bounds.set(id, copy);
153
+ grid.overflow.add(id);
154
+ _reportGridIndexing(grid, id, 'overflow', operation, 'invalid-cell-size', 0);
155
+ return true;
156
+ }
140
157
  const spanned = _spannedCellCount(cs, copy);
141
- // Written as a negated `<=` so a NaN span — a zero or non-finite cellSize makes every cell index
142
- // NaN — falls to overflow rather than through to a loop whose bounds are NaN and which therefore
143
- // never runs, silently indexing nothing.
158
+ // Written as a negated `<=` so an unrepresentable span falls to overflow rather than through to a
159
+ // loop that cannot index it.
144
160
  if (!(spanned <= MAX_INDEXED_CELLS_PER_OBJECT)) {
145
161
  grid.bounds.set(id, copy);
146
162
  grid.overflow.add(id);
147
- if (_indexingGuard !== null) {
148
- _indexingGuard({ id, mode: 'overflow', reason: null, wouldOccupyBucketCount: spanned });
149
- }
163
+ _reportGridIndexing(grid, id, 'overflow', operation, null, spanned);
150
164
  return true;
151
165
  }
152
166
  const cx0 = _cellIndex(copy.minX, cs);
@@ -191,13 +205,16 @@ function _insertIntoGrid(grid, id, bounds) {
191
205
  // usually stays inside this range, so its dominant cost becomes four field writes instead of a
192
206
  // remove-and-reinsert walk. Every mode or range transition keeps using the shared slow path below.
193
207
  function _updateGridObject(grid, id, bounds) {
208
+ const wasMissing = !grid.bounds.has(id) && !grid.declined.has(id);
194
209
  const previous = grid.bounds.get(id);
195
210
  if (previous !== undefined &&
196
211
  !grid.overflow.has(id) &&
197
212
  Number.isFinite(bounds.minX) &&
198
213
  Number.isFinite(bounds.minY) &&
199
214
  Number.isFinite(bounds.maxX) &&
200
- Number.isFinite(bounds.maxY)) {
215
+ Number.isFinite(bounds.maxY) &&
216
+ bounds.minX <= bounds.maxX &&
217
+ bounds.minY <= bounds.maxY) {
201
218
  const cs = grid.cellSize;
202
219
  const spanned = _spannedCellCount(cs, bounds);
203
220
  if (spanned <= MAX_INDEXED_CELLS_PER_OBJECT &&
@@ -213,7 +230,12 @@ function _updateGridObject(grid, id, bounds) {
213
230
  }
214
231
  }
215
232
  _removeFromGrid(grid, id);
216
- return _insertIntoGrid(grid, id, bounds);
233
+ const inserted = _insertIntoGrid(grid, id, bounds, 'update');
234
+ if (wasMissing) {
235
+ const explanation = _explainGridIndexing(grid, id);
236
+ _reportGridIndexing(grid, id, explanation.mode, 'update', 'missing-id', 0);
237
+ }
238
+ return inserted;
217
239
  }
218
240
  // Reports whether an AABB contains the point (`x`,`y`), reusing the geometry rectangle helper.
219
241
  function _isSpatialAabbContainsPoint(aabb, x, y) {
@@ -335,11 +357,14 @@ function _queryGridOverflowPairs(grid, out) {
335
357
  function _queryGridPairs(grid, out) {
336
358
  out.length = 0;
337
359
  const cs = grid.cellSize;
360
+ const list = grid.pairIds;
338
361
  for (const cell of grid.cells.values()) {
339
362
  const ids = cell.ids;
340
363
  if (ids.size < 2)
341
364
  continue;
342
- const list = [...ids];
365
+ list.length = 0;
366
+ for (const id of ids)
367
+ list.push(id);
343
368
  for (let i = 0; i < list.length; i++) {
344
369
  for (let j = i + 1; j < list.length; j++) {
345
370
  let a = list[i];
@@ -363,6 +388,11 @@ function _queryGridPairs(grid, out) {
363
388
  if (grid.overflow.size !== 0)
364
389
  _queryGridOverflowPairs(grid, out);
365
390
  }
391
+ function _reportGridIndexing(grid, id, mode, operation, reason, wouldOccupyBucketCount) {
392
+ if (_indexingGuard === null)
393
+ return;
394
+ _indexingGuard({ cellSize: grid.cellSize, id, mode, operation, reason, wouldOccupyBucketCount });
395
+ }
366
396
  // Gathers the ids in the cell containing the point, then confirms each against its real bounds. A
367
397
  // single cell holds each id at most once, so no dedup pass is needed. Overflowed objects hold no cell
368
398
  // and are tested directly; they cannot collide with the cell gather, so no dedup is needed there
@@ -532,10 +562,8 @@ function _spannedCellCount(cellSize, aabb) {
532
562
  const cy1 = _cellIndex(aabb.maxY, cellSize);
533
563
  return (cx1 - cx0 + 1) * (cy1 - cy0 + 1);
534
564
  }
535
- // Diagnostics seam: enableSpatialGuards (separately imported, so its message text and its
536
- // @flighthq/log dependency shake out of a production bundle) fills this, and the insert path reaches
537
- // it through the null check. Not enabling guards costs one comparison per declined-or-overflowed
538
- // insert — and nothing at all on the ordinary path.
565
+ // Diagnostics seam filled by setSpatialIndexingGuard. Caller-facing text stays in the separate
566
+ // formatSpatialIndexingNotice module, so production pays only the null checks at noteworthy sites.
539
567
  let _indexingGuard = null;
540
568
  // Reused scratch rectangles for the geometry overlap/containment helpers. Only ever read+written
541
569
  // within a single non-nested helper call, so sharing them across the module allocates nothing per
@@ -1 +1 @@
1
- {"version":3,"file":"uniformGrid.js","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uniformGrid.js","sourceRoot":"","sources":["../src/uniformGrid.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/spatial",
3
- "version": "0.3.0-next.1392.f0bd0cc",
3
+ "version": "0.3.0-next.1422.b585c0c",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -36,8 +36,8 @@
36
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@flighthq/geometry": "0.3.0-next.1392.f0bd0cc",
40
- "@flighthq/types": "0.3.0-next.1392.f0bd0cc"
39
+ "@flighthq/geometry": "0.3.0-next.1422.b585c0c",
40
+ "@flighthq/types": "0.3.0-next.1422.b585c0c"
41
41
  },
42
42
  "devDependencies": {
43
43
  "typescript": "^5.3.0"
@@ -11,8 +11,10 @@ afterEach(() => {
11
11
  describe('formatSpatialIndexingNotice', () => {
12
12
  it('names the sentinel to check for a decline', () => {
13
13
  const message = formatSpatialIndexingNotice({
14
+ cellSize: 10,
14
15
  id: 3,
15
16
  mode: 'declined',
17
+ operation: 'insert',
16
18
  reason: 'non-finite-bounds',
17
19
  wouldOccupyBucketCount: 0,
18
20
  });
@@ -23,8 +25,10 @@ describe('formatSpatialIndexingNotice', () => {
23
25
 
24
26
  it('names the span and the cell-size cause for an overflow, without calling it wrong', () => {
25
27
  const message = formatSpatialIndexingNotice({
28
+ cellSize: 1,
26
29
  id: 4,
27
30
  mode: 'overflow',
31
+ operation: 'insert',
28
32
  reason: null,
29
33
  wouldOccupyBucketCount: 40000,
30
34
  });
@@ -36,10 +40,50 @@ describe('formatSpatialIndexingNotice', () => {
36
40
  expect(message).toContain('Results are unaffected');
37
41
  });
38
42
 
43
+ it('explains invalid cell sizes, inverted bounds, and missing ids', () => {
44
+ expect(
45
+ formatSpatialIndexingNotice({
46
+ cellSize: 0,
47
+ id: 1,
48
+ mode: 'overflow',
49
+ operation: 'insert',
50
+ reason: 'invalid-cell-size',
51
+ wouldOccupyBucketCount: 0,
52
+ }),
53
+ ).toContain('cellSize must be a positive finite number');
54
+ expect(
55
+ formatSpatialIndexingNotice({
56
+ cellSize: 10,
57
+ id: 2,
58
+ mode: 'declined',
59
+ operation: 'update',
60
+ reason: 'inverted-bounds',
61
+ wouldOccupyBucketCount: 0,
62
+ }),
63
+ ).toContain('minX/minY must not exceed maxX/maxY');
64
+ expect(
65
+ formatSpatialIndexingNotice({
66
+ cellSize: 10,
67
+ id: 3,
68
+ mode: 'absent',
69
+ operation: 'remove',
70
+ reason: 'missing-id',
71
+ wouldOccupyBucketCount: 0,
72
+ }),
73
+ ).toContain('removal was a no-op');
74
+ });
75
+
39
76
  it('says plainly that a mode it does not cover carries no advice', () => {
40
- expect(formatSpatialIndexingNotice({ id: 5, mode: 'cells', reason: null, wouldOccupyBucketCount: 4 })).toContain(
41
- 'no caller-facing advice',
42
- );
77
+ expect(
78
+ formatSpatialIndexingNotice({
79
+ cellSize: 10,
80
+ id: 5,
81
+ mode: 'cells',
82
+ operation: 'insert',
83
+ reason: null,
84
+ wouldOccupyBucketCount: 4,
85
+ }),
86
+ ).toContain('no caller-facing advice');
43
87
  });
44
88
 
45
89
  it('formats what the grid actually hands a guard', () => {
@@ -50,8 +94,22 @@ describe('formatSpatialIndexingNotice', () => {
50
94
  grid.insertSpatialObject(9, { minX: 0, minY: 0, maxX: 199, maxY: 199 });
51
95
  grid.insertSpatialObject(10, { minX: NaN, minY: 0, maxX: 1, maxY: 1 });
52
96
  expect(notices.map(formatSpatialIndexingNotice)).toEqual([
53
- formatSpatialIndexingNotice({ id: 9, mode: 'overflow', reason: null, wouldOccupyBucketCount: 40000 }),
54
- formatSpatialIndexingNotice({ id: 10, mode: 'declined', reason: 'non-finite-bounds', wouldOccupyBucketCount: 0 }),
97
+ formatSpatialIndexingNotice({
98
+ cellSize: 1,
99
+ id: 9,
100
+ mode: 'overflow',
101
+ operation: 'insert',
102
+ reason: null,
103
+ wouldOccupyBucketCount: 40000,
104
+ }),
105
+ formatSpatialIndexingNotice({
106
+ cellSize: 1,
107
+ id: 10,
108
+ mode: 'declined',
109
+ operation: 'insert',
110
+ reason: 'non-finite-bounds',
111
+ wouldOccupyBucketCount: 0,
112
+ }),
55
113
  ]);
56
114
  expect(notices.map(formatSpatialIndexingNotice)[0]).toContain('40000 cells');
57
115
  });
@@ -17,6 +17,172 @@ function pairKeys(pairs: readonly SpatialPair[]): string[] {
17
17
  return pairs.map((p) => `${Math.min(p.a, p.b)}-${Math.max(p.a, p.b)}`).sort();
18
18
  }
19
19
 
20
+ function bruteForcePairKeys(objects: ReadonlyMap<SpatialObjectId, Readonly<SpatialAabb>>, cellSize: number): string[] {
21
+ const entries = [...objects];
22
+ const pairs: string[] = [];
23
+ for (let i = 0; i < entries.length; i++) {
24
+ for (let j = i + 1; j < entries.length; j++) {
25
+ const [aId, a] = entries[i];
26
+ const [bId, b] = entries[j];
27
+ if (
28
+ isOverflowBounds(a, cellSize) || isOverflowBounds(b, cellSize)
29
+ ? boundsOverlap(a, b)
30
+ : boundsShareCell(a, b, cellSize)
31
+ ) {
32
+ pairs.push(`${Math.min(aId, bId)}-${Math.max(aId, bId)}`);
33
+ }
34
+ }
35
+ }
36
+ return pairs.sort();
37
+ }
38
+
39
+ function boundsContainPoint(bounds: Readonly<SpatialAabb>, x: number, y: number): boolean {
40
+ return x >= bounds.minX && x <= bounds.maxX && y >= bounds.minY && y <= bounds.maxY;
41
+ }
42
+
43
+ function boundsIntersectRay(bounds: Readonly<SpatialAabb>, ox: number, oy: number, dx: number, dy: number): boolean {
44
+ let tMin = -Infinity;
45
+ let tMax = Infinity;
46
+ if (dx === 0) {
47
+ if (ox < bounds.minX || ox > bounds.maxX) return false;
48
+ } else {
49
+ const tx0 = (bounds.minX - ox) / dx;
50
+ const tx1 = (bounds.maxX - ox) / dx;
51
+ tMin = Math.max(tMin, Math.min(tx0, tx1));
52
+ tMax = Math.min(tMax, Math.max(tx0, tx1));
53
+ }
54
+ if (dy === 0) {
55
+ if (oy < bounds.minY || oy > bounds.maxY) return false;
56
+ } else {
57
+ const ty0 = (bounds.minY - oy) / dy;
58
+ const ty1 = (bounds.maxY - oy) / dy;
59
+ tMin = Math.max(tMin, Math.min(ty0, ty1));
60
+ tMax = Math.min(tMax, Math.max(ty0, ty1));
61
+ }
62
+ return tMax >= tMin && tMax >= 0;
63
+ }
64
+
65
+ function boundsShareCell(a: Readonly<SpatialAabb>, b: Readonly<SpatialAabb>, cellSize: number): boolean {
66
+ return (
67
+ Math.max(Math.floor(a.minX / cellSize), Math.floor(b.minX / cellSize)) <=
68
+ Math.min(Math.floor(a.maxX / cellSize), Math.floor(b.maxX / cellSize)) &&
69
+ Math.max(Math.floor(a.minY / cellSize), Math.floor(b.minY / cellSize)) <=
70
+ Math.min(Math.floor(a.maxY / cellSize), Math.floor(b.maxY / cellSize))
71
+ );
72
+ }
73
+
74
+ function createTestRandom(seed: number): () => number {
75
+ let state = seed >>> 0;
76
+ return () => {
77
+ state ^= state << 13;
78
+ state ^= state >>> 17;
79
+ state ^= state << 5;
80
+ return (state >>> 0) / 0x1_0000_0000;
81
+ };
82
+ }
83
+
84
+ function isOverflowBounds(bounds: Readonly<SpatialAabb>, cellSize: number): boolean {
85
+ const width = Math.floor(bounds.maxX / cellSize) - Math.floor(bounds.minX / cellSize) + 1;
86
+ const height = Math.floor(bounds.maxY / cellSize) - Math.floor(bounds.minY / cellSize) + 1;
87
+ return width * height > MAX_INDEXED_CELLS_PER_OBJECT;
88
+ }
89
+
90
+ function sortedIds(ids: readonly SpatialObjectId[]): SpatialObjectId[] {
91
+ return [...ids].sort((a, b) => a - b);
92
+ }
93
+
94
+ describe('brute-force property coverage', () => {
95
+ it('matches pair, region, point, and ray oracles through seeded cell and overflow churn', () => {
96
+ const cellSize = 4;
97
+ for (const seed of [0x1357_9bdf, 0x2468_ace0, 0x5eed_f00d, 0xc0ff_ee42]) {
98
+ const random = createTestRandom(seed);
99
+ const grid = createUniformGridSpatialBackend(cellSize);
100
+ const objects = new Map<SpatialObjectId, SpatialAabb>();
101
+
102
+ function randomBounds(overflow: boolean): SpatialAabb {
103
+ const minX = Math.floor(random() * 160) - 80 + random();
104
+ const minY = Math.floor(random() * 160) - 80 + random();
105
+ const width = overflow ? cellSize * (34 + Math.floor(random() * 12)) : 0.25 + random() * 12;
106
+ const height = overflow ? cellSize * (34 + Math.floor(random() * 12)) : 0.25 + random() * 12;
107
+ return { minX, minY, maxX: minX + width, maxY: minY + height };
108
+ }
109
+
110
+ function expectMatchesBruteForce(label: string): void {
111
+ const pairs: SpatialPair[] = [];
112
+ grid.querySpatialPairs(pairs);
113
+ expect(pairKeys(pairs), `${label}: pairs`).toEqual(bruteForcePairKeys(objects, cellSize));
114
+
115
+ const regionMinX = random() * 240 - 120;
116
+ const regionMinY = random() * 240 - 120;
117
+ const region: SpatialAabb = {
118
+ minX: regionMinX,
119
+ minY: regionMinY,
120
+ maxX: regionMinX + 1 + random() * 80,
121
+ maxY: regionMinY + 1 + random() * 80,
122
+ };
123
+ const regionActual: SpatialObjectId[] = [];
124
+ grid.querySpatialRegion(region, regionActual);
125
+ const regionExpected = [...objects].filter(([, bounds]) => boundsOverlap(bounds, region)).map(([id]) => id);
126
+ expect(sortedIds(regionActual), `${label}: region`).toEqual(sortedIds(regionExpected));
127
+
128
+ const pointX = random() * 320 - 160;
129
+ const pointY = random() * 320 - 160;
130
+ const pointActual: SpatialObjectId[] = [];
131
+ grid.querySpatialPoint(pointX, pointY, pointActual);
132
+ const pointExpected = [...objects]
133
+ .filter(([, bounds]) => boundsContainPoint(bounds, pointX, pointY))
134
+ .map(([id]) => id);
135
+ expect(sortedIds(pointActual), `${label}: point`).toEqual(sortedIds(pointExpected));
136
+
137
+ const rayX = random() * 400 - 200;
138
+ const rayY = random() * 400 - 200;
139
+ let rayDx = random() * 2 - 1;
140
+ let rayDy = random() * 2 - 1;
141
+ if (random() < 0.1) rayDx = 0;
142
+ if (random() < 0.1) rayDy = 0;
143
+ const rayActual: SpatialObjectId[] = [];
144
+ grid.querySpatialRay(rayX, rayY, rayDx, rayDy, rayActual);
145
+ const rayExpected = [...objects]
146
+ .filter(([, bounds]) => boundsIntersectRay(bounds, rayX, rayY, rayDx, rayDy))
147
+ .map(([id]) => id);
148
+ expect(sortedIds(rayActual), `${label}: ray`).toEqual(sortedIds(rayExpected));
149
+ }
150
+
151
+ const ordinary = randomBounds(false);
152
+ objects.set(0, ordinary);
153
+ grid.insertSpatialObject(0, ordinary);
154
+ expectMatchesBruteForce(`seed ${seed}, ordinary`);
155
+
156
+ const overflow = randomBounds(true);
157
+ objects.set(0, overflow);
158
+ grid.updateSpatialObject(0, overflow);
159
+ expect(grid.explainSpatialIndexing(0).mode).toBe('overflow');
160
+ expectMatchesBruteForce(`seed ${seed}, overflow`);
161
+
162
+ const ordinaryAgain = randomBounds(false);
163
+ objects.set(0, ordinaryAgain);
164
+ grid.updateSpatialObject(0, ordinaryAgain);
165
+ expect(grid.explainSpatialIndexing(0).mode).toBe('cells');
166
+ expectMatchesBruteForce(`seed ${seed}, cells again`);
167
+
168
+ for (let step = 0; step < 100; step++) {
169
+ const id = Math.floor(random() * 18);
170
+ if (random() < 0.72) {
171
+ const bounds = randomBounds(random() < 0.22);
172
+ if (objects.has(id)) grid.updateSpatialObject(id, bounds);
173
+ else if (random() < 0.5) grid.insertSpatialObject(id, bounds);
174
+ else grid.updateSpatialObject(id, bounds);
175
+ objects.set(id, bounds);
176
+ } else {
177
+ grid.removeSpatialObject(id);
178
+ objects.delete(id);
179
+ }
180
+ expectMatchesBruteForce(`seed ${seed}, step ${step}`);
181
+ }
182
+ }
183
+ });
184
+ });
185
+
20
186
  describe('cell range across every transition that can strand it', () => {
21
187
  // Chief's class-not-instance rule applied to the ray-hang defect. The bug was never "removal after
22
188
  // overflow"; it was that a separately-maintained `empty` flag could disagree with the cells it
@@ -460,13 +626,49 @@ describe('oversized-extent bound', () => {
460
626
  });
461
627
  });
462
628
 
629
+ describe('ray edge cases', () => {
630
+ it('finds objects along a ray that passes exactly through cell corners', () => {
631
+ const grid = createUniformGridSpatialBackend(10);
632
+ grid.insertSpatialObject(1, { minX: 10, minY: 10, maxX: 12, maxY: 12 });
633
+ grid.insertSpatialObject(2, { minX: 20, minY: 20, maxX: 22, maxY: 22 });
634
+ const out: SpatialObjectId[] = [];
635
+ grid.querySpatialRay(-5, -5, 1, 1, out);
636
+ expect(sortedIds(out)).toEqual([1, 2]);
637
+ });
638
+
639
+ it('finds an object when the ray starts inside its bounds', () => {
640
+ const grid = createUniformGridSpatialBackend(10);
641
+ grid.insertSpatialObject(1, { minX: 5, minY: 5, maxX: 15, maxY: 15 });
642
+ const out: SpatialObjectId[] = [];
643
+ grid.querySpatialRay(10, 10, -1, 0, out);
644
+ expect(out).toEqual([1]);
645
+ });
646
+
647
+ it('clips a ray entering the occupied range from far outside', () => {
648
+ const grid = createUniformGridSpatialBackend(10);
649
+ grid.insertSpatialObject(1, { minX: 100, minY: 30, maxX: 110, maxY: 40 });
650
+ const out: SpatialObjectId[] = [];
651
+ grid.querySpatialRay(-1e9, 35, 1, 0, out);
652
+ expect(out).toEqual([1]);
653
+ });
654
+ });
655
+
463
656
  describe('setSpatialIndexingGuard', () => {
464
657
  it('reports a decline with its reason, and no span', () => {
465
658
  const notices: SpatialIndexingNotice[] = [];
466
659
  setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
467
660
  const grid = createUniformGridSpatialBackend(10);
468
661
  grid.insertSpatialObject(7, { minX: NaN, minY: 0, maxX: 10, maxY: 10 });
469
- expect(notices).toEqual([{ id: 7, mode: 'declined', reason: 'non-finite-bounds', wouldOccupyBucketCount: 0 }]);
662
+ expect(notices).toEqual([
663
+ {
664
+ cellSize: 10,
665
+ id: 7,
666
+ mode: 'declined',
667
+ operation: 'insert',
668
+ reason: 'non-finite-bounds',
669
+ wouldOccupyBucketCount: 0,
670
+ },
671
+ ]);
470
672
  });
471
673
 
472
674
  it('reports an overflow with the span the bound refused to walk', () => {
@@ -474,7 +676,87 @@ describe('setSpatialIndexingGuard', () => {
474
676
  setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
475
677
  const grid = createUniformGridSpatialBackend(1);
476
678
  grid.insertSpatialObject(7, { minX: 0, minY: 0, maxX: 199, maxY: 199 });
477
- expect(notices).toEqual([{ id: 7, mode: 'overflow', reason: null, wouldOccupyBucketCount: 40000 }]);
679
+ expect(notices).toEqual([
680
+ {
681
+ cellSize: 1,
682
+ id: 7,
683
+ mode: 'overflow',
684
+ operation: 'insert',
685
+ reason: null,
686
+ wouldOccupyBucketCount: 40000,
687
+ },
688
+ ]);
689
+ });
690
+
691
+ it('reports an invalid cell size and keeps results correct through the bounded overflow path', () => {
692
+ const notices: SpatialIndexingNotice[] = [];
693
+ setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
694
+ for (const cellSize of [0, -1]) {
695
+ const grid = createUniformGridSpatialBackend(cellSize);
696
+ expect(grid.insertSpatialObject(7, { minX: 0, minY: 0, maxX: 10, maxY: 10 })).toBe(true);
697
+ const point: SpatialObjectId[] = [];
698
+ grid.querySpatialPoint(5, 5, point);
699
+ expect(point).toEqual([7]);
700
+ }
701
+ expect(notices).toEqual(
702
+ [0, -1].map((cellSize) => ({
703
+ cellSize,
704
+ id: 7,
705
+ mode: 'overflow',
706
+ operation: 'insert',
707
+ reason: 'invalid-cell-size',
708
+ wouldOccupyBucketCount: 0,
709
+ })),
710
+ );
711
+ });
712
+
713
+ it('declines and reports inverted bounds', () => {
714
+ const notices: SpatialIndexingNotice[] = [];
715
+ setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
716
+ const grid = createUniformGridSpatialBackend(10);
717
+ expect(grid.insertSpatialObject(7, { minX: 10, minY: 0, maxX: 0, maxY: 10 })).toBe(false);
718
+ expect(grid.explainSpatialIndexing(7)).toEqual({
719
+ bucketCount: 0,
720
+ id: 7,
721
+ mode: 'declined',
722
+ reason: 'inverted-bounds',
723
+ });
724
+ expect(notices).toEqual([
725
+ {
726
+ cellSize: 10,
727
+ id: 7,
728
+ mode: 'declined',
729
+ operation: 'insert',
730
+ reason: 'inverted-bounds',
731
+ wouldOccupyBucketCount: 0,
732
+ },
733
+ ]);
734
+ });
735
+
736
+ it('reports update and remove operations whose id was never inserted', () => {
737
+ const notices: SpatialIndexingNotice[] = [];
738
+ setSpatialIndexingGuard((notice) => notices.push({ ...notice }));
739
+ const grid = createUniformGridSpatialBackend(10);
740
+ expect(grid.updateSpatialObject(7, { minX: 0, minY: 0, maxX: 5, maxY: 5 })).toBe(true);
741
+ grid.removeSpatialObject(8);
742
+ expect(notices).toEqual([
743
+ {
744
+ cellSize: 10,
745
+ id: 7,
746
+ mode: 'cells',
747
+ operation: 'update',
748
+ reason: 'missing-id',
749
+ wouldOccupyBucketCount: 0,
750
+ },
751
+ {
752
+ cellSize: 10,
753
+ id: 8,
754
+ mode: 'absent',
755
+ operation: 'remove',
756
+ reason: 'missing-id',
757
+ wouldOccupyBucketCount: 0,
758
+ },
759
+ ]);
478
760
  });
479
761
 
480
762
  it('stays silent on the ordinary path', () => {