@osmix/core 0.0.2 → 0.1.1

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 (104) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +118 -107
  3. package/dist/src/entities.d.ts +103 -9
  4. package/dist/src/entities.d.ts.map +1 -1
  5. package/dist/src/entities.js +101 -11
  6. package/dist/src/entities.js.map +1 -1
  7. package/dist/src/ids.d.ts +82 -13
  8. package/dist/src/ids.d.ts.map +1 -1
  9. package/dist/src/ids.js +103 -31
  10. package/dist/src/ids.js.map +1 -1
  11. package/dist/src/index.d.ts +31 -5
  12. package/dist/src/index.d.ts.map +1 -1
  13. package/dist/src/index.js +33 -5
  14. package/dist/src/index.js.map +1 -1
  15. package/dist/src/nodes.d.ts +91 -21
  16. package/dist/src/nodes.d.ts.map +1 -1
  17. package/dist/src/nodes.js +191 -44
  18. package/dist/src/nodes.js.map +1 -1
  19. package/dist/src/osm.d.ts +99 -0
  20. package/dist/src/osm.d.ts.map +1 -0
  21. package/dist/src/osm.js +165 -0
  22. package/dist/src/osm.js.map +1 -0
  23. package/dist/src/relations.d.ts +112 -20
  24. package/dist/src/relations.d.ts.map +1 -1
  25. package/dist/src/relations.js +298 -35
  26. package/dist/src/relations.js.map +1 -1
  27. package/dist/src/stringtable.d.ts +78 -14
  28. package/dist/src/stringtable.d.ts.map +1 -1
  29. package/dist/src/stringtable.js +105 -26
  30. package/dist/src/stringtable.js.map +1 -1
  31. package/dist/src/tags.d.ts +117 -18
  32. package/dist/src/tags.d.ts.map +1 -1
  33. package/dist/src/tags.js +177 -30
  34. package/dist/src/tags.js.map +1 -1
  35. package/dist/src/typed-arrays.d.ts +85 -11
  36. package/dist/src/typed-arrays.d.ts.map +1 -1
  37. package/dist/src/typed-arrays.js +88 -9
  38. package/dist/src/typed-arrays.js.map +1 -1
  39. package/dist/src/utils.d.ts +35 -1
  40. package/dist/src/utils.d.ts.map +1 -1
  41. package/dist/src/utils.js +69 -10
  42. package/dist/src/utils.js.map +1 -1
  43. package/dist/src/ways.d.ts +91 -27
  44. package/dist/src/ways.d.ts.map +1 -1
  45. package/dist/src/ways.js +229 -69
  46. package/dist/src/ways.js.map +1 -1
  47. package/dist/test/memory.test.d.ts +7 -0
  48. package/dist/test/memory.test.d.ts.map +1 -0
  49. package/dist/test/memory.test.js +29 -0
  50. package/dist/test/memory.test.js.map +1 -0
  51. package/dist/test/mock-osm.d.ts +3 -3
  52. package/dist/test/mock-osm.d.ts.map +1 -1
  53. package/dist/test/mock-osm.js +3 -3
  54. package/dist/test/mock-osm.js.map +1 -1
  55. package/dist/test/tags-search.test.d.ts +2 -0
  56. package/dist/test/tags-search.test.d.ts.map +1 -0
  57. package/dist/test/tags-search.test.js +56 -0
  58. package/dist/test/tags-search.test.js.map +1 -0
  59. package/dist/test/typed-arrays.test.js +19 -17
  60. package/dist/test/typed-arrays.test.js.map +1 -1
  61. package/package.json +11 -13
  62. package/src/entities.ts +147 -22
  63. package/src/ids.ts +126 -45
  64. package/src/index.ts +34 -5
  65. package/src/nodes.ts +248 -58
  66. package/src/osm.ts +222 -0
  67. package/src/relations.ts +396 -54
  68. package/src/stringtable.ts +123 -36
  69. package/src/tags.ts +220 -46
  70. package/src/typed-arrays.ts +97 -10
  71. package/src/types/geoflatbush.d.ts +37 -0
  72. package/src/types/geokdbush.d.ts +37 -0
  73. package/src/types/kdbush.d.ts +24 -6
  74. package/src/utils.ts +80 -14
  75. package/src/ways.ts +260 -84
  76. package/test/memory.test.ts +38 -0
  77. package/test/mock-osm.ts +8 -8
  78. package/test/tags-search.test.ts +60 -0
  79. package/test/typed-arrays.test.ts +5 -6
  80. package/dist/src/osmix.d.ts +0 -88
  81. package/dist/src/osmix.d.ts.map +0 -1
  82. package/dist/src/osmix.js +0 -438
  83. package/dist/src/osmix.js.map +0 -1
  84. package/dist/test/extract.bench.d.ts +0 -2
  85. package/dist/test/extract.bench.d.ts.map +0 -1
  86. package/dist/test/extract.bench.js +0 -23
  87. package/dist/test/extract.bench.js.map +0 -1
  88. package/dist/test/extract.test.d.ts +0 -2
  89. package/dist/test/extract.test.d.ts.map +0 -1
  90. package/dist/test/extract.test.js +0 -127
  91. package/dist/test/extract.test.js.map +0 -1
  92. package/dist/test/read.test.d.ts +0 -2
  93. package/dist/test/read.test.d.ts.map +0 -1
  94. package/dist/test/read.test.js +0 -17
  95. package/dist/test/read.test.js.map +0 -1
  96. package/dist/test/write.test.d.ts +0 -2
  97. package/dist/test/write.test.d.ts.map +0 -1
  98. package/dist/test/write.test.js +0 -55
  99. package/dist/test/write.test.js.map +0 -1
  100. package/src/osmix.ts +0 -556
  101. package/test/extract.bench.ts +0 -29
  102. package/test/extract.test.ts +0 -161
  103. package/test/read.test.ts +0 -22
  104. package/test/write.test.ts +0 -69
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { BufferConstructor, ResizeableTypedArray } from "../src/typed-arrays";
3
3
  describe("typed array helpers", () => {
4
4
  it("selects the appropriate buffer constructor", () => {
@@ -78,23 +78,25 @@ describe("typed array helpers", () => {
78
78
  expect(arr.array.length).toBe(8);
79
79
  expect(Array.from(arr.slice(0, arr.length))).toEqual([1, 2, 3, 4, 5]);
80
80
  });
81
- it.runIf(typeof SharedArrayBuffer !== "undefined")("grows shared buffers in place", () => {
82
- const backing = new SharedArrayBuffer(8, {
83
- maxByteLength: 32,
81
+ if (typeof SharedArrayBuffer !== "undefined") {
82
+ it("grows shared buffers in place", () => {
83
+ const backing = new SharedArrayBuffer(8, {
84
+ maxByteLength: 32,
85
+ });
86
+ const seed = new Uint8Array(backing);
87
+ seed.set([1, 2, 3, 4, 5, 6, 7, 8]);
88
+ const arr = ResizeableTypedArray.from(Uint8Array, backing);
89
+ arr.bufferSize = arr.buffer.byteLength;
90
+ arr.maxByteLength = backing.maxByteLength;
91
+ arr.items = arr.array.length;
92
+ const originalBuffer = arr.buffer;
93
+ arr.push(9);
94
+ expect(arr.buffer).toBe(originalBuffer);
95
+ expect(arr.array.length).toBe(16);
96
+ expect(arr.buffer.byteLength).toBe(16);
97
+ expect(Array.from(arr.slice(0, 9))).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]);
84
98
  });
85
- const seed = new Uint8Array(backing);
86
- seed.set([1, 2, 3, 4, 5, 6, 7, 8]);
87
- const arr = ResizeableTypedArray.from(Uint8Array, backing);
88
- arr.bufferSize = arr.buffer.byteLength;
89
- arr.maxByteLength = backing.maxByteLength;
90
- arr.items = arr.array.length;
91
- const originalBuffer = arr.buffer;
92
- arr.push(9);
93
- expect(arr.buffer).toBe(originalBuffer);
94
- expect(arr.array.length).toBe(16);
95
- expect(arr.buffer.byteLength).toBe(16);
96
- expect(Array.from(arr.slice(0, 9))).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]);
97
- });
99
+ }
98
100
  });
99
101
  });
100
102
  //# sourceMappingURL=typed-arrays.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typed-arrays.test.js","sourceRoot":"","sources":["../../test/typed-arrays.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typed-arrays.test.js","sourceRoot":"","sources":["../../test/typed-arrays.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@osmix/core",
4
4
  "type": "module",
5
- "version": "0.0.2",
5
+ "version": "0.1.1",
6
6
  "description": "An OSM PBF reader, writer, and merge tool written in TypeScript",
7
7
  "main": "./src/index.ts",
8
8
  "publishConfig": {
@@ -32,24 +32,22 @@
32
32
  },
33
33
  "sideEffects": false,
34
34
  "scripts": {
35
- "build": "tsc",
36
- "bench": "vitest bench",
35
+ "build": "tsc --excludeDirectories test",
36
+ "bench": "bun test --bench",
37
37
  "prepublishOnly": "tsc",
38
- "test": "vitest",
39
- "typecheck": "tsc --noEmit"
38
+ "test": "bun test",
39
+ "typecheck": "tsgo --noEmit"
40
40
  },
41
41
  "devDependencies": {
42
- "@types/geojson": "catalog:",
43
- "@types/node": "catalog:",
44
- "typescript": "catalog:",
45
- "vitest": "catalog:"
42
+ "@osmix/pbf": "workspace:*",
43
+ "@types/bun": "catalog:",
44
+ "typescript": "catalog:"
46
45
  },
47
46
  "dependencies": {
48
- "@osmix/json": "workspace:*",
49
- "@osmix/pbf": "workspace:*",
50
47
  "@osmix/shared": "workspace:*",
51
48
  "flatbush": "^4.4.1",
52
- "kdbush": "mourner/kdbush#16416cd",
53
- "sweepline-intersections": "^1.5.0"
49
+ "geoflatbush": "^2.0.0",
50
+ "geokdbush": "^2.0.1",
51
+ "kdbush": "mourner/kdbush#16416cd"
54
52
  }
55
53
  }
package/src/entities.ts CHANGED
@@ -1,59 +1,152 @@
1
- import type { OsmEntity, OsmEntityType, OsmTags } from "@osmix/json"
2
- import { type IdOrIndex, Ids, type IdsTransferables } from "./ids"
3
- import type StringTable from "./stringtable"
4
- import { Tags, type TagsTransferables } from "./tags"
1
+ /**
2
+ * Base class for OSM entity collections.
3
+ *
4
+ * Provides common ID and tag storage, streaming iteration, and sorted access.
5
+ * Subclasses implement entity-specific storage and spatial indexing.
6
+ *
7
+ * @module
8
+ */
5
9
 
6
- export interface EntitiesTransferables
7
- extends IdsTransferables,
8
- TagsTransferables {}
10
+ import type {
11
+ GeoBbox2D,
12
+ OsmEntity,
13
+ OsmEntityType,
14
+ OsmTags,
15
+ } from "@osmix/shared/types"
16
+ import type { IdOrIndex, Ids, IdsTransferables } from "./ids"
17
+ import type { Tags, TagsTransferables } from "./tags"
18
+ import type { BufferType } from "./typed-arrays"
19
+ import type { ContentHasher } from "./utils"
9
20
 
21
+ /**
22
+ * Serializable representation of an Entities collection for worker transfer.
23
+ * Combines ID and tag transferables; subclasses add entity-specific data.
24
+ */
25
+ export interface EntitiesTransferables<T extends BufferType = BufferType>
26
+ extends IdsTransferables<T>,
27
+ TagsTransferables<T> {}
28
+
29
+ /**
30
+ * Abstract base for typed entity collections.
31
+ *
32
+ * Lifecycle:
33
+ * 1. **Ingest**: `addEntity()` (no lookups).
34
+ * 2. **Finalize**: `buildIndex()`.
35
+ * 3. **Query**: Lookups and iteration enabled.
36
+ */
10
37
  export abstract class Entities<T extends OsmEntity> {
38
+ /** The type of entity stored in this collection ("node", "way", or "relation"). */
11
39
  indexType: OsmEntityType
12
- stringTable: StringTable
40
+ /** ID storage and lookup */
13
41
  ids: Ids
42
+ /** Tag storage and search */
14
43
  tags: Tags
15
44
 
16
- private indexBuilt = false
45
+ /** Whether buildIndex() has been called */
46
+ protected indexBuilt = false
17
47
 
18
- constructor(
19
- indexType: OsmEntityType,
20
- stringTable: StringTable,
21
- ids?: Ids,
22
- tags?: Tags,
23
- ) {
24
- this.stringTable = stringTable
48
+ /**
49
+ * Create a new Entities collection.
50
+ * @param indexType - The entity type ("node", "way", or "relation").
51
+ * @param ids - The ID storage instance.
52
+ * @param tags - The tag storage instance.
53
+ */
54
+ constructor(indexType: OsmEntityType, ids: Ids, tags: Tags) {
25
55
  this.indexType = indexType
26
- this.ids = ids ?? new Ids()
27
- this.tags = tags ?? new Tags(stringTable)
56
+ this.ids = ids
57
+ this.tags = tags
58
+ }
59
+
60
+ /**
61
+ * Get transferable objects for passing to another thread.
62
+ */
63
+ transferables(): EntitiesTransferables {
64
+ return {
65
+ ...this.ids.transferables(),
66
+ ...this.tags.transferables(),
67
+ }
28
68
  }
29
69
 
30
- get isReady() {
31
- return this.ids.isReady && this.tags.isReady && this.indexBuilt
70
+ /**
71
+ * Check if the index is built and ready for use.
72
+ */
73
+ isReady() {
74
+ return this.ids.isReady() && this.tags.isReady() && this.indexBuilt
32
75
  }
33
76
 
77
+ /** Number of entities in this collection. */
34
78
  get size() {
35
79
  return this.ids.size
36
80
  }
37
81
 
82
+ /**
83
+ * Compact entity-specific typed arrays.
84
+ * Called by `buildIndex()` after ID and tag indexes are built.
85
+ * @abstract
86
+ */
38
87
  abstract buildEntityIndex(): void
39
88
 
89
+ /**
90
+ * Finalize indexes.
91
+ * Must be called after adding entities and before querying.
92
+ */
40
93
  buildIndex() {
41
- console.time(`${this.indexType}Index.finish`)
94
+ if (this.indexBuilt) return
95
+ console.time(`${this.indexType}Index.buildIndex`)
42
96
  this.ids.buildIndex()
43
97
  this.tags.buildIndex()
44
98
  this.buildEntityIndex()
45
99
  this.indexBuilt = true
46
- console.timeEnd(`${this.indexType}Index.finish`)
100
+ console.timeEnd(`${this.indexType}Index.buildIndex`)
47
101
  }
48
102
 
103
+ /**
104
+ * Get the bounding box of an entity.
105
+ * @param idOrIndex - Entity identifier (by ID or internal index).
106
+ * @returns Geographic bounding box [minLon, minLat, maxLon, maxLat].
107
+ * @abstract
108
+ */
109
+ abstract getEntityBbox(idOrIndex: IdOrIndex): GeoBbox2D
110
+
111
+ /**
112
+ * Reconstruct a full entity object from index data.
113
+ * @param index - Internal array index.
114
+ * @param id - OSM entity ID.
115
+ * @param tags - Optional pre-fetched tags.
116
+ * @returns The complete entity object.
117
+ * @abstract
118
+ */
49
119
  abstract getFullEntity(index: number, id: number, tags?: OsmTags): T
50
120
 
121
+ /**
122
+ * Add an entity to the index. Tags can be provided as an array of keys and values, or as an object.
123
+ */
124
+ addEntity(id: number, tags: number[], values: number[]): number
125
+ addEntity(id: number, tags: OsmTags): number
126
+ addEntity(id: number, tags: OsmTags | number[], values?: number[]): number {
127
+ const entityIndex = this.ids.add(id)
128
+ if (Array.isArray(tags)) {
129
+ if (values === undefined)
130
+ throw Error("Values are required when tags is an array")
131
+ this.tags.addTagKeysAndValues(entityIndex, tags, values)
132
+ } else {
133
+ this.tags.addTags(entityIndex, tags)
134
+ }
135
+ return entityIndex
136
+ }
137
+
138
+ /**
139
+ * Get an entity by ID or index.
140
+ */
51
141
  get(idOrIndex: IdOrIndex): T | null {
52
142
  const [index, id] = this.ids.idOrIndex(idOrIndex)
53
143
  if (index === -1) return null
54
144
  return this.getFullEntity(index, id, this.tags.getTags(index))
55
145
  }
56
146
 
147
+ /**
148
+ * Get an entity by index.
149
+ */
57
150
  getByIndex(index: number): T {
58
151
  return this.getFullEntity(
59
152
  index,
@@ -62,6 +155,9 @@ export abstract class Entities<T extends OsmEntity> {
62
155
  )
63
156
  }
64
157
 
158
+ /**
159
+ * Get multiple entities by their indexes.
160
+ */
65
161
  getEntitiesByIndex(indexes: number[]): T[] {
66
162
  const entities: T[] = []
67
163
  for (const index of indexes) {
@@ -72,12 +168,18 @@ export abstract class Entities<T extends OsmEntity> {
72
168
  return entities
73
169
  }
74
170
 
171
+ /**
172
+ * Iterate over all entities in the index.
173
+ */
75
174
  *[Symbol.iterator](): Generator<T> {
76
175
  for (let i = 0; i < this.size; i++) {
77
176
  yield this.getFullEntity(i, this.ids.at(i), this.tags.getTags(i))
78
177
  }
79
178
  }
80
179
 
180
+ /**
181
+ * Get an entity by ID.
182
+ */
81
183
  getById(id: number): T | null {
82
184
  const index = this.ids.getIndexFromId(id)
83
185
  if (index !== -1)
@@ -85,6 +187,9 @@ export abstract class Entities<T extends OsmEntity> {
85
187
  return null
86
188
  }
87
189
 
190
+ /**
191
+ * Iterate over entities sorted by ID.
192
+ */
88
193
  *sorted(): Generator<T> {
89
194
  for (const id of this.ids.sorted) {
90
195
  const index = this.ids.getIndexFromId(id)
@@ -92,4 +197,24 @@ export abstract class Entities<T extends OsmEntity> {
92
197
  yield this.getFullEntity(index, id, this.tags.getTags(index))
93
198
  }
94
199
  }
200
+
201
+ /**
202
+ * Search for entities with a specific tag key and optional value.
203
+ */
204
+ search(key: string, val?: string): T[] {
205
+ const keyIndex = this.tags.find(key)
206
+ const entities = this.tags
207
+ .hasKey(keyIndex)
208
+ .map((index) => this.getByIndex(index))
209
+ if (val === undefined) return entities
210
+ return entities.filter((entity) => entity.tags?.[key] === val)
211
+ }
212
+
213
+ /**
214
+ * Update a ContentHasher with this entity collection's base data (IDs and tags).
215
+ * Subclasses should override to add entity-specific data.
216
+ */
217
+ updateHash(hasher: ContentHasher): ContentHasher {
218
+ return this.ids.updateHash(this.tags.updateHash(hasher))
219
+ }
95
220
  }
package/src/ids.ts CHANGED
@@ -1,92 +1,131 @@
1
+ /**
2
+ * ID storage and lookup for OSM entities.
3
+ *
4
+ * Uses a two-level binary search (anchor array + block search) to map 64-bit OSM IDs
5
+ * to internal array indices. Balances memory usage with O(log n) lookup speed.
6
+ *
7
+ * @module
8
+ */
9
+
1
10
  import { assertValue } from "@osmix/shared/assert"
2
11
  import {
3
12
  BufferConstructor,
4
13
  type BufferType,
5
- ResizeableTypedArray,
14
+ ResizeableTypedArray as RTA,
6
15
  } from "./typed-arrays"
16
+ import type { ContentHasher } from "./utils"
7
17
 
18
+ /**
19
+ * Union type for looking up entities by either OSM ID or internal array index.
20
+ */
8
21
  export type IdOrIndex = { id: number } | { index: number }
9
22
 
23
+ /**
24
+ * Number of IDs per anchor block for the two-level binary search.
25
+ * Smaller values increase anchor array size but speed up block-level search;
26
+ * larger values reduce anchor overhead but slow the final search.
27
+ */
10
28
  const BLOCK_SIZE = 256
11
29
 
12
- export interface IdsTransferables {
13
- ids: BufferType
14
- sortedIds: BufferType
15
- sortedIdPositionToIndex: BufferType
16
- anchors: BufferType
30
+ /**
31
+ * Serializable state for worker transfer.
32
+ */
33
+ export interface IdsTransferables<T extends BufferType = BufferType> {
34
+ /** Entity IDs in insertion order. */
35
+ ids: T
36
+ /** Sorted IDs for binary search (aliases `ids` if already sorted). */
37
+ sortedIds: T
38
+ /** Maps sorted position → original insertion index. */
39
+ sortedIdPositionToIndex: T
40
+ /** Anchor array: every BLOCK_SIZE-th sorted ID. */
41
+ anchors: T
42
+ /** True if IDs were inserted in ascending order. */
17
43
  idsAreSorted: boolean
18
44
  }
19
45
 
20
46
  /**
21
- * Efficiently store and lookup IDs.
47
+ * Efficiently store and lookup OSM entity IDs.
22
48
  *
23
- * This is used to store IDs in a sorted array and then use binary search to find the index of an ID.
24
- * Maps max out at 2^32 IDs.
49
+ * Stores 64-bit IDs in a Float64Array and maintains a sorted index for O(log n) lookups.
50
+ * Max capacity: ~2^32 entities.
25
51
  */
26
52
  export class Ids {
27
- private ids: ResizeableTypedArray<Float64Array>
53
+ /** All IDs in insertion order */
54
+ private ids: RTA<Float64Array>
55
+ /** Whether buildIndex() has been called */
28
56
  private indexBuilt = false
57
+ /** True if IDs were added in ascending order (allows index optimization) */
29
58
  private idsAreSorted = true
59
+ /** Sorted view of IDs for binary search */
30
60
  private idsSorted: Float64Array
61
+ /** Maps position in sorted array → original insertion index */
31
62
  private sortedIdPositionToIndex: Uint32Array
63
+ /** Anchor array for two-level binary search: every BLOCK_SIZE-th sorted ID */
32
64
  private anchors: Float64Array
33
65
 
34
- static from({
35
- ids,
36
- sortedIds,
37
- sortedIdPositionToIndex,
38
- anchors,
39
- idsAreSorted,
40
- }: IdsTransferables) {
41
- const idIndex = new Ids()
42
- idIndex.ids = ResizeableTypedArray.from(Float64Array, ids)
43
- idIndex.idsSorted = new Float64Array(sortedIds)
44
- idIndex.sortedIdPositionToIndex = new Uint32Array(sortedIdPositionToIndex)
45
- idIndex.anchors = new Float64Array(anchors)
46
- idIndex.indexBuilt = true
47
- idIndex.idsAreSorted = idsAreSorted
48
- return idIndex
49
- }
50
-
51
- constructor() {
52
- this.ids = new ResizeableTypedArray(Float64Array)
53
- this.idsSorted = new Float64Array(new BufferConstructor(0))
54
- this.sortedIdPositionToIndex = new Uint32Array(new BufferConstructor(0))
55
- this.anchors = new Float64Array(new BufferConstructor(0))
56
- }
57
-
58
- transferables(): IdsTransferables {
59
- return {
60
- ids: this.ids.array.buffer,
61
- sortedIds: this.idsSorted.buffer,
62
- sortedIdPositionToIndex: this.sortedIdPositionToIndex.buffer,
63
- anchors: this.anchors.buffer,
64
- idsAreSorted: this.idsAreSorted,
66
+ /**
67
+ * Create a new Ids index.
68
+ * @param transferables - Optional serialized state to reconstruct from.
69
+ */
70
+ constructor(transferables?: IdsTransferables) {
71
+ if (transferables) {
72
+ this.ids = RTA.from(Float64Array, transferables.ids)
73
+ this.idsSorted = new Float64Array(transferables.sortedIds)
74
+ this.sortedIdPositionToIndex = new Uint32Array(
75
+ transferables.sortedIdPositionToIndex,
76
+ )
77
+ this.anchors = new Float64Array(transferables.anchors)
78
+ this.idsAreSorted = transferables.idsAreSorted
79
+ this.indexBuilt = true
80
+ } else {
81
+ this.ids = new RTA(Float64Array)
82
+ this.idsSorted = new Float64Array(new BufferConstructor(0))
83
+ this.sortedIdPositionToIndex = new Uint32Array(new BufferConstructor(0))
84
+ this.anchors = new Float64Array(new BufferConstructor(0))
65
85
  }
66
86
  }
67
87
 
88
+ /** Number of IDs stored in this index. */
68
89
  get size() {
69
90
  return this.ids.length
70
91
  }
71
92
 
72
- get isReady() {
93
+ /** Returns true if buildIndex() has been called and lookups are enabled. */
94
+ isReady() {
73
95
  return this.indexBuilt
74
96
  }
75
97
 
98
+ /** Returns true if IDs were inserted in ascending order. */
76
99
  isSorted() {
77
100
  return this.idsAreSorted
78
101
  }
79
102
 
80
- add(id: number): void {
103
+ /**
104
+ * Add an ID to the index.
105
+ * @param id - The OSM entity ID to add.
106
+ * @returns The internal array index where this ID was stored.
107
+ * @throws If the index has already been built.
108
+ */
109
+ add(id: number): number {
81
110
  if (this.indexBuilt) throw Error("ID index already built.")
82
111
  if (this.ids.length > 0 && id < this.ids.at(-1)) this.idsAreSorted = false
83
- this.ids.push(id)
112
+ return this.ids.push(id)
84
113
  }
85
114
 
115
+ /**
116
+ * Get the ID at a specific internal index.
117
+ * @param index - The internal array index.
118
+ * @returns The OSM entity ID at that index.
119
+ */
86
120
  at(index: number): number {
87
121
  return this.ids.at(index)
88
122
  }
89
123
 
124
+ /**
125
+ * Check if an ID exists in this index.
126
+ * @param id - The OSM entity ID to check.
127
+ * @returns True if the ID exists in this index.
128
+ */
90
129
  has(id: number): boolean {
91
130
  return this.getIndexFromId(id) !== -1
92
131
  }
@@ -158,7 +197,13 @@ export class Ids {
158
197
  this.indexBuilt = true
159
198
  }
160
199
 
161
- // Lookup id → index
200
+ /**
201
+ * Look up the internal array index for an OSM entity ID.
202
+ *
203
+ * @param id - The OSM entity ID to look up.
204
+ * @returns The internal array index, or -1 if not found.
205
+ * @throws If the index has not been built.
206
+ */
162
207
  getIndexFromId(id: number): number {
163
208
  if (!this.indexBuilt) throw Error("IdIndex not built.")
164
209
 
@@ -204,7 +249,43 @@ export class Ids {
204
249
  return [i.index, this.at(i.index)]
205
250
  }
206
251
 
252
+ /** Returns the sorted array of IDs for iteration. */
207
253
  get sorted() {
208
254
  return this.idsSorted
209
255
  }
256
+
257
+ /**
258
+ * Get transferable buffers for passing to another thread.
259
+ * @returns Serializable representation of this index.
260
+ */
261
+ transferables(): IdsTransferables {
262
+ return {
263
+ ids: this.ids.array.buffer,
264
+ sortedIds: this.idsSorted.buffer,
265
+ sortedIdPositionToIndex: this.sortedIdPositionToIndex.buffer,
266
+ anchors: this.anchors.buffer,
267
+ idsAreSorted: this.idsAreSorted,
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Get the approximate memory requirements for a given number of IDs in bytes.
273
+ */
274
+ static getBytesRequired(count: number) {
275
+ if (count === 0) return 0
276
+ return (
277
+ count * Float64Array.BYTES_PER_ELEMENT + // ids
278
+ count * Float64Array.BYTES_PER_ELEMENT + // sortedIds
279
+ count * Uint32Array.BYTES_PER_ELEMENT + // sortedIdPositionToIndex
280
+ Math.ceil(count / BLOCK_SIZE) * Float64Array.BYTES_PER_ELEMENT // anchors
281
+ )
282
+ }
283
+
284
+ /**
285
+ * Update a ContentHasher with the IDs data.
286
+ * Uses the sorted IDs for consistent hashing regardless of insertion order.
287
+ */
288
+ updateHash(hasher: ContentHasher): ContentHasher {
289
+ return hasher.update(this.idsSorted)
290
+ }
210
291
  }
package/src/index.ts CHANGED
@@ -1,7 +1,36 @@
1
+ /**
2
+ * @osmix/core - In-memory OSM entity storage with spatial indexing.
3
+ *
4
+ * Efficiently stores and queries OpenStreetMap entities (nodes, ways, relations).
5
+ *
6
+ * Features:
7
+ * - **Memory-efficient**: Uses typed arrays and Int32Array microdegrees.
8
+ * - **Spatial indexing**: KDBush (points) and Flatbush (bboxes) for fast geographic queries.
9
+ * - **Worker-ready**: Zero-copy transfer via `transferables()`.
10
+ * - **Tag indexing**: Fast reverse lookup by tag key.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { Osm } from "@osmix/core"
15
+ * const osm = new Osm({ id: "example" })
16
+ * osm.nodes.addNode({ id: 1, lon: -122.4, lat: 47.6, tags: { name: "Seattle" } })
17
+ * osm.buildIndexes()
18
+ * osm.buildSpatialIndexes()
19
+ * const nearby = osm.nodes.findIndexesWithinRadius(-122.4, 47.6, 10)
20
+ * ```
21
+ *
22
+ * @module @osmix/core
23
+ */
24
+
1
25
  /// <reference path="./types/kdbush.d.ts" />
26
+ /// <reference path="./types/geokdbush.d.ts" />
27
+ /// <reference path="./types/geoflatbush.d.ts" />
2
28
 
3
- export { Nodes } from "./nodes"
4
- export { Osmix } from "./osmix"
5
- export { Relations } from "./relations"
6
- export { throttle } from "./utils"
7
- export { Ways } from "./ways"
29
+ export * from "./nodes"
30
+ export * from "./osm"
31
+ export * from "./relations"
32
+ export * from "./stringtable"
33
+ export * from "./tags"
34
+ export { BufferConstructor, type BufferType } from "./typed-arrays"
35
+ export * from "./utils" // TODO Move into shared?
36
+ export * from "./ways"