albedo-node 0.5.3

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.
package/bun.lock ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "albedo-node",
6
+ "devDependencies": {
7
+ "@types/node": "^24.0.0",
8
+ "typescript": "^5.9.3",
9
+ },
10
+ },
11
+ },
12
+ "packages": {
13
+ "@types/node": ["@types/node@24.10.13", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg=="],
14
+
15
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
16
+
17
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
18
+ }
19
+ }
@@ -0,0 +1,64 @@
1
+ type ByteBuffer = Uint8Array;
2
+ type BucketHandle = object;
3
+ type ListIteratorHandle = object;
4
+ type TransformIteratorHandle = object;
5
+ interface IndexOptions {
6
+ unique: boolean;
7
+ sparse: boolean;
8
+ reverse: boolean;
9
+ }
10
+ interface IndexInfo {
11
+ name: string;
12
+ unique: boolean;
13
+ sparse: boolean;
14
+ reverse: boolean;
15
+ }
16
+ interface ObjectIdInstance {
17
+ buffer: ByteBuffer;
18
+ toString(): string;
19
+ }
20
+ interface ObjectIdConstructor {
21
+ new (buffer?: ByteBuffer): ObjectIdInstance;
22
+ fromString(hex: string): ObjectIdInstance;
23
+ }
24
+ interface AlbedoModule {
25
+ ObjectId: ObjectIdConstructor;
26
+ serialize(value: unknown): Uint8Array;
27
+ deserialize<T = unknown>(data: ByteBuffer): T;
28
+ open(path: string): BucketHandle;
29
+ close(bucket: BucketHandle): void;
30
+ list(bucket: BucketHandle, query: object): ListIteratorHandle;
31
+ listClose(cursor: ListIteratorHandle): void;
32
+ listData(cursor: ListIteratorHandle): unknown | null;
33
+ insert(bucket: BucketHandle, doc: ByteBuffer | object): void;
34
+ ensureIndex(bucket: BucketHandle, name: string, options: IndexOptions): void;
35
+ listIndexes(bucket: BucketHandle): Record<string, IndexInfo>;
36
+ dropIndex(bucket: BucketHandle, name: string): void;
37
+ delete(bucket: BucketHandle, query: object): void;
38
+ transform(bucket: BucketHandle, query: object): TransformIteratorHandle;
39
+ transformClose(iter: TransformIteratorHandle): void;
40
+ transformData(iter: TransformIteratorHandle): unknown | null;
41
+ transformApply(iter: TransformIteratorHandle, replace: ByteBuffer | object | null): void;
42
+ setReplicationCallback(bucket: BucketHandle, callback: (data: Uint8Array) => void): void;
43
+ applyReplicationBatch(bucket: BucketHandle, data: ByteBuffer): void;
44
+ }
45
+ declare const albedo: AlbedoModule;
46
+ export default albedo;
47
+ export declare const BSON: {
48
+ serialize: (value: unknown) => Uint8Array;
49
+ deserialize: <T = unknown>(data: ByteBuffer) => T;
50
+ };
51
+ export declare class Bucket {
52
+ private handle;
53
+ constructor(handle: object);
54
+ static open(path: string): Bucket;
55
+ close(): void;
56
+ insert(doc: object | ByteBuffer): void;
57
+ get indexes(): Record<string, IndexInfo>;
58
+ ensureIndex(name: string, options: IndexOptions): void;
59
+ dropIndex(name: string): void;
60
+ list<T>(query: object): Generator<T>;
61
+ transformIterator<T>(query: object): Generator<T, undefined, null | object>;
62
+ setReplicationCallback(callback: (data: Uint8Array) => void): void;
63
+ applyReplicationBatch(data: Uint8Array): void;
64
+ }
package/dist/index.js ADDED
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Bucket = exports.BSON = void 0;
4
+ const platformSuffix = process.platform == "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
5
+ const archSuffix = process.arch === "x64" ? "x86_64" : process.arch === "arm64" ? "aarch64" : process.arch;
6
+ const isMusl = process.versions.libc && process.versions.libc.includes("musl");
7
+ const libcSuffix = isMusl ? "_musl" : "";
8
+ const albedo = require(`../native/albedo.${archSuffix}_${platformSuffix}${libcSuffix}.node`);
9
+ exports.default = albedo;
10
+ exports.BSON = {
11
+ serialize: albedo.serialize,
12
+ deserialize: albedo.deserialize,
13
+ };
14
+ class Bucket {
15
+ handle;
16
+ constructor(handle) {
17
+ this.handle = handle;
18
+ }
19
+ static open(path) {
20
+ const handle = albedo.open(path);
21
+ return new Bucket(handle);
22
+ }
23
+ close() {
24
+ albedo.close(this.handle);
25
+ }
26
+ insert(doc) {
27
+ albedo.insert(this.handle, doc);
28
+ }
29
+ get indexes() {
30
+ return albedo.listIndexes(this.handle);
31
+ }
32
+ ensureIndex(name, options) {
33
+ albedo.ensureIndex(this.handle, name, options);
34
+ }
35
+ dropIndex(name) {
36
+ albedo.dropIndex(this.handle, name);
37
+ }
38
+ *list(query) {
39
+ const cursor = albedo.list(this.handle, query);
40
+ try {
41
+ let data;
42
+ while ((data = albedo.listData(cursor)) !== null) {
43
+ yield data;
44
+ }
45
+ }
46
+ finally {
47
+ albedo.listClose(cursor);
48
+ }
49
+ }
50
+ *transformIterator(query) {
51
+ const iter = albedo.transform(this.handle, query);
52
+ try {
53
+ let data;
54
+ while ((data = albedo.transformData(iter)) !== null) {
55
+ const newDoc = yield data;
56
+ albedo.transformApply(iter, newDoc);
57
+ }
58
+ }
59
+ finally {
60
+ albedo.transformClose(iter);
61
+ }
62
+ }
63
+ setReplicationCallback(callback) {
64
+ albedo.setReplicationCallback(this.handle, callback);
65
+ }
66
+ applyReplicationBatch(data) {
67
+ albedo.applyReplicationBatch(this.handle, data);
68
+ }
69
+ }
70
+ exports.Bucket = Bucket;
@@ -0,0 +1,15 @@
1
+ # example
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run index.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.3.1. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
@@ -0,0 +1,108 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 0,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "example",
7
+ "dependencies": {
8
+ "albedo-node": "../",
9
+ "better-sqlite3": "^12.6.2",
10
+ },
11
+ "devDependencies": {
12
+ "@types/bun": "latest",
13
+ },
14
+ "peerDependencies": {
15
+ "typescript": "^5",
16
+ },
17
+ },
18
+ },
19
+ "packages": {
20
+ "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
21
+
22
+ "@types/node": ["@types/node@24.10.13", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg=="],
23
+
24
+ "albedo-node": ["albedo-node@file:..", { "devDependencies": { "@types/node": "^24.0.0", "typescript": "^5.9.3" } }],
25
+
26
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
27
+
28
+ "better-sqlite3": ["better-sqlite3@12.6.2", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA=="],
29
+
30
+ "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
31
+
32
+ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
33
+
34
+ "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
35
+
36
+ "bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
37
+
38
+ "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
39
+
40
+ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
41
+
42
+ "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
43
+
44
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
45
+
46
+ "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
47
+
48
+ "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
49
+
50
+ "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
51
+
52
+ "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
53
+
54
+ "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
55
+
56
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
57
+
58
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
59
+
60
+ "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
61
+
62
+ "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
63
+
64
+ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
65
+
66
+ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
67
+
68
+ "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
69
+
70
+ "node-abi": ["node-abi@3.87.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ=="],
71
+
72
+ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
73
+
74
+ "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
75
+
76
+ "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
77
+
78
+ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
79
+
80
+ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
81
+
82
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
83
+
84
+ "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
85
+
86
+ "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
87
+
88
+ "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
89
+
90
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
91
+
92
+ "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
93
+
94
+ "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
95
+
96
+ "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
97
+
98
+ "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
99
+
100
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
101
+
102
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
103
+
104
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
105
+
106
+ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
107
+ }
108
+ }
@@ -0,0 +1,95 @@
1
+ import { BSON, Bucket } from "albedo-node";
2
+ import Database from "bun:sqlite";
3
+ import { unlinkSync } from "fs";
4
+
5
+ const docNum = 100000;
6
+
7
+ const sqliteDb = new Database("db.sqlite");
8
+ sqliteDb
9
+ .prepare(
10
+ `
11
+ CREATE TABLE IF NOT EXISTS documents (
12
+ _id INTEGER PRIMARY KEY,
13
+ doc JSON
14
+ );
15
+ `,
16
+ )
17
+ .run();
18
+
19
+ sqliteDb.prepare("drop index IF EXISTS idx_doc_id;").run();
20
+ sqliteDb.prepare("create unique index idx_doc_id on documents(json_extract(doc, '$._id'));").run();
21
+
22
+ console.time("Insert 100000 documents into SQLite");
23
+ const insertStmt = sqliteDb.prepare("INSERT INTO documents (doc) VALUES (json(?))");
24
+ for (let i = 0; i < docNum; i++) {
25
+ insertStmt.run(JSON.stringify({
26
+ _id: i,
27
+ name: `Name ${i}`,
28
+ age: i,
29
+ }));
30
+ }
31
+ console.timeEnd("Insert 100000 documents into SQLite");
32
+
33
+ console.time("Query scan x 100 in SQLite");
34
+ for (let i = 0; i < 100; i++) {
35
+ const row = sqliteDb
36
+ .prepare("SELECT doc FROM documents WHERE json_extract(doc, '$.age') = ? LIMIT 100")
37
+ .get(Math.floor(Math.random() * docNum));
38
+ if (row) JSON.parse(row.doc);
39
+ }
40
+ console.timeEnd("Query scan x 100 in SQLite");
41
+
42
+ console.time("Query index x 100 in SQLite");
43
+ for (let i = 0; i < 100; i++) {
44
+ const row = sqliteDb
45
+ .prepare(
46
+ "SELECT doc FROM documents WHERE json_extract(doc, '$._id') = ? LIMIT 100",
47
+ )
48
+ .get(Math.floor(Math.random() * docNum));
49
+ if (row) JSON.parse(row.doc);
50
+ }
51
+ console.timeEnd("Query index x 100 in SQLite");
52
+
53
+ sqliteDb.close();
54
+
55
+ const bucket = Bucket.open("db.bucket");
56
+
57
+ // bucket.dropIndex("_id");
58
+
59
+ console.time("Insert 100000 documents");
60
+ for (let i = 0; i < docNum; i++) {
61
+ bucket.insert({
62
+ _id: i,
63
+ name: `Name ${i}`,
64
+ age: i,
65
+ });
66
+ }
67
+ console.timeEnd("Insert 100000 documents");
68
+
69
+ console.time("Query scan x 100");
70
+ for (let i = 0; i < 100; i++) {
71
+ bucket
72
+ .list({
73
+ query: { age: Math.floor(Math.random() * docNum) },
74
+ sector: { limit: 100 },
75
+ })
76
+ .next();
77
+ }
78
+ console.timeEnd("Query scan x 100");
79
+
80
+ console.time("Query index x 100");
81
+ for (let i = 0; i < 100; i++) {
82
+
83
+ bucket
84
+ .list({
85
+ query: { _id: Math.floor(Math.random() * docNum) },
86
+ sector: { limit: 100 },
87
+ })
88
+ .next();
89
+ }
90
+ console.timeEnd("Query index x 100");
91
+
92
+ bucket.close();
93
+
94
+ unlinkSync("db.sqlite");
95
+ unlinkSync("db.bucket");
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "example",
3
+ "module": "index.ts",
4
+ "type": "module",
5
+ "private": true,
6
+ "devDependencies": {
7
+ "@types/bun": "latest"
8
+ },
9
+ "peerDependencies": {
10
+ "typescript": "^5"
11
+ },
12
+ "dependencies": {
13
+ "albedo-node": "../",
14
+ "better-sqlite3": "^12.6.2"
15
+ }
16
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Environment setup & latest features
4
+ "lib": ["ESNext"],
5
+ "target": "ESNext",
6
+ "module": "Preserve",
7
+ "moduleDetection": "force",
8
+ "jsx": "react-jsx",
9
+ "allowJs": true,
10
+
11
+ // Bundler mode
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "verbatimModuleSyntax": true,
15
+ "noEmit": true,
16
+
17
+ // Best practices
18
+ "strict": true,
19
+ "skipLibCheck": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedIndexedAccess": true,
22
+ "noImplicitOverride": true,
23
+
24
+ // Some stricter flags (disabled by default)
25
+ "noUnusedLocals": false,
26
+ "noUnusedParameters": false,
27
+ "noPropertyAccessFromIndexSignature": false
28
+ }
29
+ }
Binary file
Binary file
Binary file
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "albedo-node",
3
+ "version": "0.5.3",
4
+ "description": "Albedo DB native bindings",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build:binding": "zig build",
9
+ "build:ts": "bun run tsc -p tsconfig.json",
10
+ "build": "bun run build:binding && bun run build:ts",
11
+ "release": "bun ./scripts/publish.ts"
12
+ },
13
+ "author": "",
14
+ "license": "MIT",
15
+ "devDependencies": {
16
+ "@types/node": "^24.0.0",
17
+ "typescript": "^5.9.3"
18
+ }
19
+ }
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env bun
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import os from "os";
5
+ import { $ } from "bun";
6
+
7
+ const dry = process.argv.includes("--dry-run");
8
+
9
+ async function main() {
10
+ const root = process.cwd();
11
+ const pkgPath = path.join(root, "package.json");
12
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
13
+
14
+ const name = pkg.name || "(unknown)";
15
+ const version = pkg.version || "0.0.0";
16
+
17
+ console.log(`🔧 Building ${name}@${version}...`);
18
+ const buildRes = await $`bun run build`;
19
+ if (buildRes.exitCode !== 0) throw new Error("build failed");
20
+
21
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), `${name.replace("/", "-")}-`));
22
+ console.log(`đŸ“Ļ Preparing publish directory: ${tmp}`);
23
+
24
+ function copyOrFail(rel: string) {
25
+ const src = path.join(root, rel);
26
+ if (!fs.existsSync(src)) throw new Error(`Required path not found: ${rel}`);
27
+ fs.cpSync(src, path.join(tmp, rel), { recursive: true });
28
+ }
29
+
30
+ // required distributables
31
+ copyOrFail("dist");
32
+ copyOrFail("native");
33
+
34
+ // copy docs if present
35
+ ["README.md", "LICENSE", "CHANGELOG.md"].forEach((f) => {
36
+ const p = path.join(root, f);
37
+ if (fs.existsSync(p)) fs.copyFileSync(p, path.join(tmp, f));
38
+ });
39
+
40
+ // sanitize package.json for publish (remove dev-only fields & scripts)
41
+ const publishPkg = { ...pkg } as Record<string, any>;
42
+ delete publishPkg.devDependencies;
43
+ delete publishPkg.scripts;
44
+ publishPkg.files = Array.from(new Set([...(publishPkg.files || []), "dist", "native"]));
45
+ if (publishPkg.private) delete publishPkg.private;
46
+
47
+ fs.writeFileSync(path.join(tmp, "package.json"), JSON.stringify(publishPkg, null, 2) + "\n");
48
+
49
+ console.log("📋 Files staged for publish:");
50
+ const lsRes = await $`ls -1`.cwd(tmp);
51
+ if (lsRes.exitCode === 0) console.log(String(lsRes.stdout || "").trim());
52
+
53
+ if (dry) {
54
+ console.log("âš ī¸ Dry run — skipping npm publish. Use --no-dry-run to actually publish.");
55
+ } else {
56
+ const packOnly = process.argv.includes("--pack-only");
57
+
58
+ console.log("âžĄī¸ Creating package tarball with `bun pm pack`...");
59
+ const packRes = await $`bun pm pack --quiet`.cwd(tmp);
60
+ if (packRes.exitCode !== 0) {
61
+ console.error(String(packRes.stderr || packRes.stdout || ""));
62
+ throw new Error(`bun pm pack failed (${packRes.exitCode})`);
63
+ }
64
+ console.log("✅ Package tarball created:", packRes.stdout.toString('utf8'));
65
+
66
+ const tarballName = String(packRes.stdout || packRes.stderr || "").trim().split(/\r?\n/).pop();
67
+ const tarballPath = path.join(tmp, tarballName || "package.tgz");
68
+ console.log(`đŸ“Ļ Packaged: ${tarballPath}`);
69
+
70
+ if (packOnly) {
71
+ console.log("â„šī¸ --pack-only provided; skipping publish.");
72
+ } else {
73
+ console.log("âžĄī¸ Publishing tarball with bun publish...");
74
+ const publishRes = await $`npm publishbun --access public ${tarballPath}`.cwd(root);
75
+ if (publishRes.exitCode !== 0) {
76
+ console.error(String(publishRes.stderr || publishRes.stdout || ""));
77
+ throw new Error(`bun publish failed (${publishRes.exitCode})`);
78
+ }
79
+ console.log("✅ Publish complete.");
80
+ }
81
+ }
82
+
83
+ fs.rmSync(tmp, { recursive: true, force: true });
84
+ console.log(`🎉 ${name}@${version} ${dry ? "(dry-run)" : "published"}`);
85
+ }
86
+
87
+ main().catch((err) => {
88
+ console.error(err);
89
+ process.exit(1);
90
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "Node",
6
+ "lib": ["ES2022"],
7
+ "types": ["node"],
8
+ "rootDir": "src",
9
+ "outDir": "dist",
10
+ "declaration": true,
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true
15
+ },
16
+ "include": ["src/index.ts"]
17
+ }