@botejs/core 0.1.3 → 0.1.4

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 (2) hide show
  1. package/README.md +69 -0
  2. package/package.json +5 -4
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # bote
2
+
3
+ a minimal, ergonomic and low-memory approach to navigating a big JSON:
4
+
5
+ ```sh
6
+ npm install @botejs/core
7
+ ```
8
+
9
+ ```ts
10
+ import { open, fromFile } from '@botejs/core'
11
+
12
+ import * as z from 'zod' // or bring your own Standard Schema validator
13
+
14
+ const User = z.object({
15
+ id: z.string(),
16
+ email: z.string(),
17
+ })
18
+
19
+ type User = z.infer<typeof User>
20
+
21
+ await using cursor = await open(fromFile('./your-big.json'))
22
+
23
+ // if you want one value
24
+ const user0: unknown = await cursor.get('/1234/users/0')
25
+
26
+ // for .get and .iter, you can supply a validator
27
+ const user1: User = await cursor.get('/1234/users/1', User)
28
+
29
+ // if you want to iterate a list of values
30
+ for await (const user of cursor.iter('/1234/users')) {
31
+ console.log(user)
32
+ }
33
+
34
+ // if you want to iterate but not fully resolve values
35
+ for await (const userCursor of cursor.walk('/1234/users')) {
36
+ const id = await userCursor.get('/id')
37
+ console.log({ id })
38
+ }
39
+
40
+ // 'await using' would normally clean up resources for you
41
+ // when it goes out of lexical scope. if you hate that,
42
+ // you can do it explicitly as well.
43
+ await cursor.close()
44
+ ```
45
+
46
+ given a **seekable** source (e.g. a file, an HTTP range) and a JSON pointer, it can retrieve values in a JSON quickly, without loading the whole thing in-memory.
47
+
48
+ here's a run (Apple M1 Pro 2021, 500MB JSON array file, cold-cache, default settings):
49
+
50
+ | operation | approach | time | js heap peak Δ | rust heap peak |
51
+ | ------------ | ---------- | --------: | -------------: | -------------: |
52
+ | items[0] | JSON.parse | 1.75 s | 1.21 GB | n/a |
53
+ | items[len/2] | JSON.parse | 1.82 s | 1.21 GB | n/a |
54
+ | items[len-1] | JSON.parse | 1.76 s | 1.21 GB | n/a |
55
+ | items[0] | bote | 1.43 ms | 25.9 KB | 94.9 KB |
56
+ | items[len/2] | bote | 328.81 ms | 1.3 MB | 56.6 MB |
57
+ | items[len-1] | bote | 636.78 ms | 1.3 MB | 56.6 MB |
58
+
59
+ ## sources
60
+
61
+ bote currently only has `fromFile` and `fromHttpRange` as pre-built sources. create your own by implementing the `Source` interface. see [./packages/core/src/sources.ts](./packages/core/src/sources.ts) on how it works.
62
+
63
+ ## status
64
+
65
+ pre-1.0 so still in development and APIs may change based on feedback, bugs and holy divinations from the coding gods.
66
+
67
+ ## license
68
+
69
+ MIT.
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@botejs/core",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/jankdc/bote.git",
8
- "directory": "packages/bote"
8
+ "directory": "packages/core"
9
9
  },
10
10
  "main": "dist/index.js",
11
11
  "types": "dist/index.d.ts",
12
12
  "files": [
13
- "dist"
13
+ "dist",
14
+ "README.md"
14
15
  ],
15
16
  "engines": {
16
17
  "node": ">= 18.17.0 < 19 || >= 20.3.0 < 21 || >= 21.1.0"
@@ -24,7 +25,7 @@
24
25
  "build:debug": "tsc --sourceMap",
25
26
  "test": "node --test --experimental-strip-types --no-warnings=ExperimentalWarning __test__/*.spec.ts",
26
27
  "lint": "oxlint src",
27
- "prepublishOnly": "tsc"
28
+ "prepublishOnly": "cp ../../README.md ./README.md && tsc"
28
29
  },
29
30
  "dependencies": {
30
31
  "@botejs/native": "workspace:*"