rbush-rs 1.0.5 → 1.0.6

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 (3) hide show
  1. package/README.md +40 -37
  2. package/package.json +4 -3
  3. package/rbush.umd.js +240 -0
package/README.md CHANGED
@@ -1,47 +1,51 @@
1
1
  # rbush-rs
2
+
2
3
  A high-performance(>5x faster), 100% Rust port of [RBush](https://github.com/mourner/rbush) spatial index library, compiled to WebAssembly.
3
4
 
4
5
  `rbush-rs` is designed to be a near drop-in replacement for `rbush`, offering significant performance improvements for bulk loading and searching massive datasets.
5
6
 
6
7
  ```diff
7
- + Import { RBush } from 'rbush-rs';
8
- - Import { RBush } from 'rbush';
8
+ + Import RBush from 'rbush-rs';
9
+ - Import RBush from 'rbush';
9
10
  ```
10
11
 
11
12
  ## Benchmark
12
13
 
13
14
  Tests performed on a dataset of 10,000 rectangles.
14
15
 
15
- | Operation | JS (rbush) | WASM (rbush-rs) | Speedup |
16
- | --- | --- | --- | --- |
17
- | **Bulk Load (Hybrid)** | 20.23 ms | **3.60 ms** | **~5.6x Faster** |
18
- | **Insert (1000 items)** | 36.58 ms | **4.04 ms** | **~9.1x Faster** |
19
- | **Remove (1000 items)** | 58.03 ms | **7.85 ms** | **~7.4x Faster** |
20
- | **Search** | 0.042 ms | **0.027 ms** | **~1.6x Faster** |
21
- | **Collides** | 0.003 ms | 0.003 ms | **1x Faster** |
22
- | **Clear** | 0.001 ms | 0.001 ms | **1x Faster** |
16
+ | Operation | JS (rbush) | WASM (rbush-rs) | Speedup |
17
+ | ----------------------- | ---------- | --------------- | ---------------- |
18
+ | **Bulk Load (Hybrid)** | 20.23 ms | **3.60 ms** | **~5.6x Faster** |
19
+ | **Insert (1000 items)** | 36.58 ms | **4.04 ms** | **~9.1x Faster** |
20
+ | **Remove (1000 items)** | 58.03 ms | **7.85 ms** | **~7.4x Faster** |
21
+ | **Search** | 0.042 ms | **0.027 ms** | **~1.6x Faster** |
22
+ | **Collides** | 0.003 ms | 0.003 ms | **1x Faster** |
23
+ | **Clear** | 0.001 ms | 0.001 ms | **1x Faster** |
23
24
 
24
- *\*Standard load is slower due to the overhead of reading JS objects into WASM. Use Hybrid Load for maximum performance.*
25
+ _\*Standard load is slower due to the overhead of reading JS objects into WASM. Use Hybrid Load for maximum performance._
25
26
 
26
27
  ## Installation
28
+
27
29
  You can install `rbush-rs` via:
28
30
 
29
31
  ### npm
32
+
30
33
  ```bash
31
34
  npm install rbush-rs
32
35
  ```
33
36
 
34
37
  ### pnpm
38
+
35
39
  ```bash
36
40
  pnpm install rbush-rs
37
41
  ```
38
42
 
39
43
  ### yarn
44
+
40
45
  ```bash
41
46
  yarn add rbush-rs
42
47
  ```
43
48
 
44
-
45
49
  ## Usage
46
50
 
47
51
  ### The "Drop-in" Replacement
@@ -49,22 +53,21 @@ yarn add rbush-rs
49
53
  Use this mode if you want to switch libraries with minimal code changes. It accepts the same data format as the original `rbush`.
50
54
 
51
55
  ```javascript
52
- import { RBush } from 'rbush-rs';
56
+ import { RBush } from "rbush-rs"
53
57
 
54
58
  // Initialize (max entries per node, default 9)
55
- const tree = new RBush(9);
59
+ const tree = new RBush(9)
56
60
 
57
61
  // Load standard data (Array of objects with minX, minY, maxX, maxY)
58
62
  const items = [
59
- { minX: 10, minY: 10, maxX: 20, maxY: 20, id: 'a' },
60
- { minX: 50, minY: 50, maxX: 60, maxY: 60, id: 'b' }
61
- ];
62
- tree.load(items);
63
+ { minX: 10, minY: 10, maxX: 20, maxY: 20, id: "a" },
64
+ { minX: 50, minY: 50, maxX: 60, maxY: 60, id: "b" },
65
+ ]
66
+ tree.load(items)
63
67
 
64
68
  // Search
65
- const results = tree.search({ minX: 0, minY: 0, maxX: 30, maxY: 30 });
66
- console.log(results); // [{ minX: 10, ... }]
67
-
69
+ const results = tree.search({ minX: 0, minY: 0, maxX: 30, maxY: 30 })
70
+ console.log(results) // [{ minX: 10, ... }]
68
71
  ```
69
72
 
70
73
  ### The "Hybrid" Load (Recommended for MAX Speed)
@@ -84,7 +87,7 @@ const flatCoords = new Float64Array(count * 4);
84
87
 
85
88
  for(let i = 0; i < count; i++) {
86
89
  const item = { minX: Math.random() * 100, minY: Math.random() * 100, maxX: ..., maxY: ..., id: i };
87
-
90
+
88
91
  // standard items array
89
92
  items.push(item);
90
93
 
@@ -112,8 +115,8 @@ All operations below work regardless of how you loaded the data (Standard or Hyb
112
115
  `rbush-rs` is highly optimized for dynamic updates, performing ~9x faster than JS.
113
116
 
114
117
  ```javascript
115
- const item = { minX: 20, minY: 20, maxX: 30, maxY: 30, id: 'c' };
116
- tree.insert(item);
118
+ const item = { minX: 20, minY: 20, maxX: 30, maxY: 30, id: "c" }
119
+ tree.insert(item)
117
120
  ```
118
121
 
119
122
  #### Removal
@@ -121,7 +124,7 @@ tree.insert(item);
121
124
  Removal is ~7x faster than JS. The item object passed must match the one in the tree (by reference equality).
122
125
 
123
126
  ```javascript
124
- tree.remove(item);
127
+ tree.remove(item)
125
128
  ```
126
129
 
127
130
  #### Collision Detection
@@ -129,7 +132,7 @@ tree.remove(item);
129
132
  Checks if there are any items in the bounding box. Faster than `search` if you don't need the actual items.
130
133
 
131
134
  ```javascript
132
- const hasCollision = tree.collides({ minX: 10, minY: 10, maxX: 20, maxY: 20 });
135
+ const hasCollision = tree.collides({ minX: 10, minY: 10, maxX: 20, maxY: 20 })
133
136
  // returns true or false
134
137
  ```
135
138
 
@@ -138,7 +141,7 @@ const hasCollision = tree.collides({ minX: 10, minY: 10, maxX: 20, maxY: 20 });
138
141
  Returns all items currently stored in the tree.
139
142
 
140
143
  ```javascript
141
- const allItems = tree.all();
144
+ const allItems = tree.all()
142
145
  ```
143
146
 
144
147
  #### Clear Tree
@@ -146,17 +149,17 @@ const allItems = tree.all();
146
149
  Removes all items and resets the tree.
147
150
 
148
151
  ```javascript
149
- tree.clear();
152
+ tree.clear()
150
153
  ```
151
154
 
152
155
  ## 🔧 API Reference
153
156
 
154
- * **`new RBush(maxEntries?: number)`**: Creates a new tree.
155
- * **`load(items: array)`**: Bulk loads standard JS objects.
156
- * **`loadHybrid(coords: Float64Array, items: array)`**: High-performance bulk load.
157
- * **`insert(item: object)`**: Inserts a single item.
158
- * **`remove(item: object)`**: Removes a specific item.
159
- * **`search(bbox: object)`**: Returns an array of items intersecting the bbox.
160
- * **`collides(bbox: object)`**: Returns `true` if any item intersects the bbox.
161
- * **`all()`**: Returns all items in the tree.
162
- * **`clear()`**: Removes all items.
157
+ - **`new RBush(maxEntries?: number)`**: Creates a new tree.
158
+ - **`load(items: array)`**: Bulk loads standard JS objects.
159
+ - **`loadHybrid(coords: Float64Array, items: array)`**: High-performance bulk load.
160
+ - **`insert(item: object)`**: Inserts a single item.
161
+ - **`remove(item: object)`**: Removes a specific item.
162
+ - **`search(bbox: object)`**: Returns an array of items intersecting the bbox.
163
+ - **`collides(bbox: object)`**: Returns `true` if any item intersects the bbox.
164
+ - **`all()`**: Returns all items in the tree.
165
+ - **`clear()`**: Removes all items.
package/package.json CHANGED
@@ -5,18 +5,19 @@
5
5
  "Preetham <ppmpreetham1@gmail.com>"
6
6
  ],
7
7
  "description": "High-performance RBush port in WebAssembly",
8
- "version": "1.0.5",
8
+ "version": "1.0.6",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "https://github.com/ppmpreetham/rbush-rs"
13
13
  },
14
- "files": [
14
+ "files": [
15
15
  "rbush_rs_bg.wasm",
16
16
  "rbush_rs.js",
17
17
  "rbush_rs_bg.js",
18
18
  "rbush_rs.d.ts",
19
- "rbush.js"
19
+ "rbush.js",
20
+ "rbush.umd.js"
20
21
  ],
21
22
  "main": "rbush.js",
22
23
  "types": "rbush_rs.d.ts",
package/rbush.umd.js ADDED
@@ -0,0 +1,240 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.RBush = factory());
5
+ })(this, (function () { 'use strict';
6
+
7
+ function _loadWasmModule (sync, filepath, src, imports) {
8
+ function _instantiateOrCompile(source, imports, stream) {
9
+ var instantiateFunc = stream ? WebAssembly.instantiateStreaming : WebAssembly.instantiate;
10
+ var compileFunc = stream ? WebAssembly.compileStreaming : WebAssembly.compile;
11
+
12
+ if (imports) {
13
+ return instantiateFunc(source, imports)
14
+ } else {
15
+ return compileFunc(source)
16
+ }
17
+ }
18
+ var isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
19
+
20
+ if (isNode) {
21
+
22
+ var fs = require("fs");
23
+ var path = require("path");
24
+
25
+ return new Promise((resolve, reject) => {
26
+ fs.readFile(path.resolve(__dirname, filepath), (error, buffer) => {
27
+ if (error != null) {
28
+ reject(error);
29
+ } else {
30
+ resolve(_instantiateOrCompile(buffer, imports, false));
31
+ }
32
+ });
33
+ });
34
+
35
+ } else {
36
+
37
+ return _instantiateOrCompile(fetch(filepath), imports, true);
38
+
39
+ }
40
+ }
41
+
42
+ function rbush_rs_bg(imports){return _loadWasmModule(0, 'c5b00a3a15dd90c3.wasm', null, imports)}
43
+
44
+ var wasm$1 = /*#__PURE__*/Object.freeze({
45
+ __proto__: null,
46
+ default: rbush_rs_bg
47
+ });
48
+
49
+ let RBush$1 = class RBush {
50
+ __destroy_into_raw() {
51
+ const ptr = this.__wbg_ptr;
52
+ this.__wbg_ptr = 0;
53
+ RBushFinalization.unregister(this);
54
+ return ptr;
55
+ }
56
+ free() {
57
+ const ptr = this.__destroy_into_raw();
58
+ wasm.__wbg_rbush_free(ptr, 0);
59
+ }
60
+ /**
61
+ * @returns {Array<any>}
62
+ */
63
+ all() {
64
+ const ret = wasm.rbush_all(this.__wbg_ptr);
65
+ return ret;
66
+ }
67
+ clear() {
68
+ wasm.rbush_clear(this.__wbg_ptr);
69
+ }
70
+ /**
71
+ * @param {any} bbox_js
72
+ * @returns {boolean}
73
+ */
74
+ collides(bbox_js) {
75
+ const ret = wasm.rbush_collides(this.__wbg_ptr, bbox_js);
76
+ return ret !== 0;
77
+ }
78
+ /**
79
+ * @param {any} data
80
+ */
81
+ fromJSON(data) {
82
+ wasm.rbush_fromJSON(this.__wbg_ptr, data);
83
+ }
84
+ /**
85
+ * @param {any} item
86
+ */
87
+ insert(item) {
88
+ wasm.rbush_insert(this.__wbg_ptr, item);
89
+ }
90
+ /**
91
+ * @param {Array<any>} data
92
+ */
93
+ load(data) {
94
+ wasm.rbush_load(this.__wbg_ptr, data);
95
+ }
96
+ /**
97
+ * @param {Float64Array} fast_coords
98
+ * @param {Array<any>} items
99
+ */
100
+ loadHybrid(fast_coords, items) {
101
+ const ptr0 = passArrayF64ToWasm0(fast_coords, wasm.__wbindgen_malloc);
102
+ const len0 = WASM_VECTOR_LEN;
103
+ wasm.rbush_loadHybrid(this.__wbg_ptr, ptr0, len0, items);
104
+ }
105
+ /**
106
+ * @param {number | null} [max_entries]
107
+ */
108
+ constructor(max_entries) {
109
+ const ret = wasm.rbush_new(isLikeNone(max_entries) ? 0x100000001 : (max_entries) >>> 0);
110
+ this.__wbg_ptr = ret >>> 0;
111
+ RBushFinalization.register(this, this.__wbg_ptr, this);
112
+ return this;
113
+ }
114
+ /**
115
+ * @param {any} item
116
+ */
117
+ remove(item) {
118
+ wasm.rbush_remove(this.__wbg_ptr, item);
119
+ }
120
+ /**
121
+ * @param {any} bbox_js
122
+ * @returns {Array<any>}
123
+ */
124
+ search(bbox_js) {
125
+ const ret = wasm.rbush_search(this.__wbg_ptr, bbox_js);
126
+ return ret;
127
+ }
128
+ /**
129
+ * @returns {any}
130
+ */
131
+ toJSON() {
132
+ const ret = wasm.rbush_toJSON(this.__wbg_ptr);
133
+ return ret;
134
+ }
135
+ };
136
+ if (Symbol.dispose) RBush$1.prototype[Symbol.dispose] = RBush$1.prototype.free;
137
+ const RBushFinalization = (typeof FinalizationRegistry === 'undefined')
138
+ ? { register: () => {}, unregister: () => {} }
139
+ : new FinalizationRegistry(ptr => wasm.__wbg_rbush_free(ptr >>> 0, 1));
140
+
141
+ let cachedFloat64ArrayMemory0 = null;
142
+ function getFloat64ArrayMemory0() {
143
+ if (cachedFloat64ArrayMemory0 === null || cachedFloat64ArrayMemory0.byteLength === 0) {
144
+ cachedFloat64ArrayMemory0 = new Float64Array(wasm.memory.buffer);
145
+ }
146
+ return cachedFloat64ArrayMemory0;
147
+ }
148
+
149
+ function isLikeNone(x) {
150
+ return x === undefined || x === null;
151
+ }
152
+
153
+ function passArrayF64ToWasm0(arg, malloc) {
154
+ const ptr = malloc(arg.length * 8, 8) >>> 0;
155
+ getFloat64ArrayMemory0().set(arg, ptr / 8);
156
+ WASM_VECTOR_LEN = arg.length;
157
+ return ptr;
158
+ }
159
+
160
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
161
+ cachedTextDecoder.decode();
162
+
163
+ let WASM_VECTOR_LEN = 0;
164
+
165
+
166
+ let wasm;
167
+ function __wbg_set_wasm(val) {
168
+ wasm = val;
169
+ }
170
+
171
+ /* @ts-self-types="./rbush_rs.d.ts" */
172
+
173
+ __wbg_set_wasm(wasm$1);
174
+ undefined();
175
+
176
+ class RBush {
177
+ constructor(maxEntries = 9) {
178
+ this._tree = new RBush$1(maxEntries);
179
+ }
180
+
181
+ toBBox(item) {
182
+ return item
183
+ }
184
+
185
+ insert(item) {
186
+ const b = this.toBBox(item);
187
+ this._tree.insert({
188
+ ...item,
189
+ minX: b.minX,
190
+ minY: b.minY,
191
+ maxX: b.maxX,
192
+ maxY: b.maxY,
193
+ });
194
+ return this
195
+ }
196
+
197
+ load(data) {
198
+ const normalized = data.map((item) => {
199
+ const b = this.toBBox(item);
200
+ return { ...item, minX: b.minX, minY: b.minY, maxX: b.maxX, maxY: b.maxY }
201
+ });
202
+ this._tree.load(normalized);
203
+ return this
204
+ }
205
+
206
+ remove(item) {
207
+ const b = this.toBBox(item);
208
+ this._tree.remove({ ...item, minX: b.minX, minY: b.minY, maxX: b.maxX, maxY: b.maxY });
209
+ return this
210
+ }
211
+
212
+ search(bbox) {
213
+ return this._tree.search(bbox)
214
+ }
215
+ collides(bbox) {
216
+ return this._tree.collides(bbox)
217
+ }
218
+ all() {
219
+ return this._tree.all()
220
+ }
221
+ clear() {
222
+ this._tree.clear();
223
+ return this
224
+ }
225
+ toJSON() {
226
+ return this._tree.toJSON()
227
+ }
228
+ fromJSON(data) {
229
+ this._tree.fromJSON(data);
230
+ return this
231
+ }
232
+
233
+ destroy() {
234
+ this._tree.free();
235
+ }
236
+ }
237
+
238
+ return RBush;
239
+
240
+ }));