@frostpillar/frostpillar-btree 0.2.0
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/LICENSE +21 -0
- package/README-JA.md +912 -0
- package/README.md +912 -0
- package/dist/InMemoryBTree.d.ts +45 -0
- package/dist/btree/autoScale.d.ts +9 -0
- package/dist/btree/bulkLoad.d.ts +5 -0
- package/dist/btree/deleteRange.d.ts +3 -0
- package/dist/btree/integrity-helpers.d.ts +6 -0
- package/dist/btree/integrity.d.ts +2 -0
- package/dist/btree/mutations.d.ts +12 -0
- package/dist/btree/navigation.d.ts +23 -0
- package/dist/btree/rangeQuery.d.ts +3 -0
- package/dist/btree/rebalance.d.ts +4 -0
- package/dist/btree/serialization.d.ts +20 -0
- package/dist/btree/stats.d.ts +2 -0
- package/dist/btree/types.d.ts +113 -0
- package/dist/chunk-ZA3EQNDI.js +1902 -0
- package/dist/concurrency/ConcurrentInMemoryBTree.d.ts +56 -0
- package/dist/concurrency/helpers.d.ts +27 -0
- package/dist/concurrency/index.d.ts +2 -0
- package/dist/concurrency/types.d.ts +41 -0
- package/dist/core.cjs +1919 -0
- package/dist/core.d.ts +4 -0
- package/dist/core.js +10 -0
- package/dist/errors.d.ts +9 -0
- package/dist/frostpillar-btree-core.min.js +1 -0
- package/dist/frostpillar-btree.min.js +1 -0
- package/dist/index.cjs +2230 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +316 -0
- package/package.json +80 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { InMemoryBTree } from './InMemoryBTree.js';
|
|
2
|
+
export type { BTreeEntry, BTreeJSON, BTreeStats, DuplicateKeyPolicy, EntryId, InMemoryBTreeConfig, RangeBounds, } from './InMemoryBTree.js';
|
|
3
|
+
export { ConcurrentInMemoryBTree } from './concurrency/index.js';
|
|
4
|
+
export type { BTreeMutation, ConcurrentInMemoryBTreeConfig, ReadMode, SharedTreeLog, SharedTreeStore, } from './concurrency/index.js';
|
|
5
|
+
export { BTreeConcurrencyError, BTreeInvariantError, BTreeValidationError, } from './errors.js';
|
|
6
|
+
export type { KeyComparator } from './btree/types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BTreeConcurrencyError,
|
|
3
|
+
BTreeInvariantError,
|
|
4
|
+
BTreeValidationError,
|
|
5
|
+
DEFAULT_MAX_BRANCH_CHILDREN,
|
|
6
|
+
DEFAULT_MAX_LEAF_ENTRIES,
|
|
7
|
+
InMemoryBTree,
|
|
8
|
+
computeAutoScaleTier
|
|
9
|
+
} from "./chunk-ZA3EQNDI.js";
|
|
10
|
+
|
|
11
|
+
// src/concurrency/helpers.ts
|
|
12
|
+
var DEFAULT_MAX_RETRIES = 16;
|
|
13
|
+
var MAX_RETRIES_LIMIT = 1024;
|
|
14
|
+
var DEFAULT_MAX_SYNC_MUTATIONS_PER_BATCH = 1e5;
|
|
15
|
+
var MAX_SYNC_MUTATIONS_PER_BATCH_LIMIT = 1e6;
|
|
16
|
+
var computeConfigFingerprint = (config) => {
|
|
17
|
+
const isAutoScale = config.autoScale === true;
|
|
18
|
+
const tier0 = isAutoScale ? computeAutoScaleTier(0) : void 0;
|
|
19
|
+
return JSON.stringify({
|
|
20
|
+
duplicateKeys: config.duplicateKeys ?? "replace",
|
|
21
|
+
maxLeafEntries: config.maxLeafEntries ?? (tier0 ? tier0.maxLeaf : DEFAULT_MAX_LEAF_ENTRIES),
|
|
22
|
+
maxBranchChildren: config.maxBranchChildren ?? (tier0 ? tier0.maxBranch : DEFAULT_MAX_BRANCH_CHILDREN),
|
|
23
|
+
enableEntryIdLookup: config.enableEntryIdLookup === true,
|
|
24
|
+
autoScale: isAutoScale
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var assertNeverMutation = (mutation) => {
|
|
28
|
+
const unknownMutation = mutation;
|
|
29
|
+
throw new BTreeConcurrencyError(
|
|
30
|
+
`Unsupported mutation type from shared store: ${String(unknownMutation.type)}`
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
var normalizeMaxRetries = (value) => {
|
|
34
|
+
if (value === void 0) {
|
|
35
|
+
return DEFAULT_MAX_RETRIES;
|
|
36
|
+
}
|
|
37
|
+
if (!Number.isInteger(value) || value < 1 || value > MAX_RETRIES_LIMIT) {
|
|
38
|
+
throw new BTreeConcurrencyError(
|
|
39
|
+
`maxRetries: integer 1\u2013${MAX_RETRIES_LIMIT} required.`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
};
|
|
44
|
+
var normalizeMaxSyncMutationsPerBatch = (value) => {
|
|
45
|
+
if (value === void 0) {
|
|
46
|
+
return DEFAULT_MAX_SYNC_MUTATIONS_PER_BATCH;
|
|
47
|
+
}
|
|
48
|
+
if (!Number.isInteger(value) || value < 1 || value > MAX_SYNC_MUTATIONS_PER_BATCH_LIMIT) {
|
|
49
|
+
throw new BTreeConcurrencyError(
|
|
50
|
+
`maxSyncMutationsPerBatch: integer 1\u2013${MAX_SYNC_MUTATIONS_PER_BATCH_LIMIT} required.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
};
|
|
55
|
+
var normalizeReadMode = (value) => {
|
|
56
|
+
if (value === void 0) {
|
|
57
|
+
return "strong";
|
|
58
|
+
}
|
|
59
|
+
if (value !== "strong" && value !== "local") {
|
|
60
|
+
throw new BTreeConcurrencyError(
|
|
61
|
+
`readMode: must be 'strong' or 'local'.`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
};
|
|
66
|
+
function assertAppendVersionContract(expectedVersion, appendResult) {
|
|
67
|
+
if (typeof appendResult !== "object" || appendResult === null) {
|
|
68
|
+
throw new BTreeConcurrencyError(
|
|
69
|
+
"Store contract: append() must return {applied, version}."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const candidate = appendResult;
|
|
73
|
+
if (typeof candidate.applied !== "boolean") {
|
|
74
|
+
throw new BTreeConcurrencyError("Store contract: applied must be boolean.");
|
|
75
|
+
}
|
|
76
|
+
if (typeof candidate.version !== "bigint") {
|
|
77
|
+
throw new BTreeConcurrencyError("Store contract: version must be bigint.");
|
|
78
|
+
}
|
|
79
|
+
if (candidate.applied && candidate.version <= expectedVersion) {
|
|
80
|
+
throw new BTreeConcurrencyError(
|
|
81
|
+
"Store contract: applied version must exceed expected."
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (!candidate.applied && candidate.version < expectedVersion) {
|
|
85
|
+
throw new BTreeConcurrencyError(
|
|
86
|
+
"Store contract: rejected version must be >= expected."
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/concurrency/ConcurrentInMemoryBTree.ts
|
|
92
|
+
var ConcurrentInMemoryBTree = class {
|
|
93
|
+
constructor(config) {
|
|
94
|
+
this.store = config.store;
|
|
95
|
+
this.maxRetries = normalizeMaxRetries(config.maxRetries);
|
|
96
|
+
this.maxSyncMutationsPerBatch = normalizeMaxSyncMutationsPerBatch(
|
|
97
|
+
config.maxSyncMutationsPerBatch
|
|
98
|
+
);
|
|
99
|
+
this.duplicateKeys = config.duplicateKeys ?? "replace";
|
|
100
|
+
this.readMode = normalizeReadMode(config.readMode);
|
|
101
|
+
this.configFingerprint = computeConfigFingerprint(config);
|
|
102
|
+
this.tree = new InMemoryBTree({
|
|
103
|
+
compareKeys: config.compareKeys,
|
|
104
|
+
maxLeafEntries: config.maxLeafEntries,
|
|
105
|
+
maxBranchChildren: config.maxBranchChildren,
|
|
106
|
+
duplicateKeys: config.duplicateKeys,
|
|
107
|
+
enableEntryIdLookup: config.enableEntryIdLookup,
|
|
108
|
+
autoScale: config.autoScale
|
|
109
|
+
});
|
|
110
|
+
this.currentVersion = 0n;
|
|
111
|
+
this.operationQueue = Promise.resolve();
|
|
112
|
+
this.initSeen = false;
|
|
113
|
+
}
|
|
114
|
+
async sync() {
|
|
115
|
+
await this.runExclusive(async () => {
|
|
116
|
+
await this.syncUnlocked();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
async syncUnlocked() {
|
|
120
|
+
const log = await this.store.getLogEntriesSince(this.currentVersion);
|
|
121
|
+
if (typeof log.version !== "bigint") {
|
|
122
|
+
throw new BTreeConcurrencyError("Store contract: version must be bigint.");
|
|
123
|
+
}
|
|
124
|
+
if (!Array.isArray(log.mutations)) {
|
|
125
|
+
throw new BTreeConcurrencyError("Store contract: mutations must be an array.");
|
|
126
|
+
}
|
|
127
|
+
if (log.mutations.length > this.maxSyncMutationsPerBatch) {
|
|
128
|
+
throw new BTreeConcurrencyError(
|
|
129
|
+
`Sync batch exceeded limit (${String(this.maxSyncMutationsPerBatch)}).`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (log.version <= this.currentVersion) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
for (const mutation of log.mutations) {
|
|
136
|
+
this.applyMutationLocal(mutation);
|
|
137
|
+
}
|
|
138
|
+
this.currentVersion = log.version;
|
|
139
|
+
}
|
|
140
|
+
applyMutationLocal(mutation) {
|
|
141
|
+
switch (mutation.type) {
|
|
142
|
+
case "init":
|
|
143
|
+
if (mutation.configFingerprint !== this.configFingerprint) {
|
|
144
|
+
throw new BTreeConcurrencyError(
|
|
145
|
+
"Config mismatch: store peers must share identical tree config."
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
this.initSeen = true;
|
|
149
|
+
return null;
|
|
150
|
+
case "put":
|
|
151
|
+
return this.tree.put(mutation.key, mutation.value);
|
|
152
|
+
case "remove":
|
|
153
|
+
return this.tree.remove(mutation.key);
|
|
154
|
+
case "removeById":
|
|
155
|
+
return this.tree.removeById(mutation.entryId);
|
|
156
|
+
case "updateById":
|
|
157
|
+
return this.tree.updateById(mutation.entryId, mutation.value);
|
|
158
|
+
case "popFirst":
|
|
159
|
+
return this.tree.popFirst();
|
|
160
|
+
case "popLast":
|
|
161
|
+
return this.tree.popLast();
|
|
162
|
+
default:
|
|
163
|
+
return assertNeverMutation(mutation);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
runExclusive(operation) {
|
|
167
|
+
const run = async () => operation();
|
|
168
|
+
const result = this.operationQueue.then(run, run);
|
|
169
|
+
this.operationQueue = result.then(
|
|
170
|
+
() => void 0,
|
|
171
|
+
() => void 0
|
|
172
|
+
);
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
readOp(fn) {
|
|
176
|
+
return this.runExclusive(async () => {
|
|
177
|
+
if (this.readMode === "strong") {
|
|
178
|
+
await this.syncUnlocked();
|
|
179
|
+
}
|
|
180
|
+
return fn(this.tree);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async appendMutationAndApplyUnlocked(evaluate) {
|
|
184
|
+
for (let attempt = 0; attempt < this.maxRetries; attempt += 1) {
|
|
185
|
+
await this.syncUnlocked();
|
|
186
|
+
const mutation = evaluate(this.tree);
|
|
187
|
+
if (mutation === null) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
const expectedVersion = this.currentVersion;
|
|
191
|
+
const mutations = this.initSeen ? [mutation] : [{ type: "init", configFingerprint: this.configFingerprint }, mutation];
|
|
192
|
+
const appendResult = await this.store.append(expectedVersion, mutations);
|
|
193
|
+
assertAppendVersionContract(expectedVersion, appendResult);
|
|
194
|
+
if (appendResult.applied) {
|
|
195
|
+
for (const m of mutations) {
|
|
196
|
+
if (m === mutation) break;
|
|
197
|
+
this.applyMutationLocal(m);
|
|
198
|
+
}
|
|
199
|
+
const localResult = this.applyMutationLocal(mutation);
|
|
200
|
+
this.currentVersion = appendResult.version;
|
|
201
|
+
return localResult;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
throw new BTreeConcurrencyError(
|
|
205
|
+
`Mutation failed after ${String(this.maxRetries)} retries.`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
async put(key, value) {
|
|
209
|
+
return this.runExclusive(async () => {
|
|
210
|
+
return this.appendMutationAndApplyUnlocked(
|
|
211
|
+
(tree) => {
|
|
212
|
+
if (this.duplicateKeys === "reject" && tree.hasKey(key)) {
|
|
213
|
+
throw new BTreeValidationError("Duplicate key rejected.");
|
|
214
|
+
}
|
|
215
|
+
return { type: "put", key, value };
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
async remove(key) {
|
|
221
|
+
return this.runExclusive(async () => {
|
|
222
|
+
return this.appendMutationAndApplyUnlocked(
|
|
223
|
+
(tree) => {
|
|
224
|
+
return tree.hasKey(key) ? { type: "remove", key } : null;
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
async removeById(entryId) {
|
|
230
|
+
return this.runExclusive(async () => {
|
|
231
|
+
return this.appendMutationAndApplyUnlocked(
|
|
232
|
+
(tree) => {
|
|
233
|
+
return tree.peekById(entryId) !== null ? { type: "removeById", entryId } : null;
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
async updateById(entryId, value) {
|
|
239
|
+
return this.runExclusive(async () => {
|
|
240
|
+
return this.appendMutationAndApplyUnlocked(
|
|
241
|
+
(tree) => {
|
|
242
|
+
return tree.peekById(entryId) !== null ? { type: "updateById", entryId, value } : null;
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async popFirst() {
|
|
248
|
+
return this.runExclusive(async () => {
|
|
249
|
+
return this.appendMutationAndApplyUnlocked((tree) => {
|
|
250
|
+
return tree.peekFirst() !== null ? { type: "popFirst" } : null;
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
async get(key) {
|
|
255
|
+
return this.readOp((tree) => tree.get(key));
|
|
256
|
+
}
|
|
257
|
+
async hasKey(key) {
|
|
258
|
+
return this.readOp((tree) => tree.hasKey(key));
|
|
259
|
+
}
|
|
260
|
+
async findFirst(key) {
|
|
261
|
+
return this.readOp((tree) => tree.findFirst(key));
|
|
262
|
+
}
|
|
263
|
+
async findLast(key) {
|
|
264
|
+
return this.readOp((tree) => tree.findLast(key));
|
|
265
|
+
}
|
|
266
|
+
async range(startKey, endKey, options) {
|
|
267
|
+
return this.readOp((tree) => tree.range(startKey, endKey, options));
|
|
268
|
+
}
|
|
269
|
+
async snapshot() {
|
|
270
|
+
return this.readOp((tree) => tree.snapshot());
|
|
271
|
+
}
|
|
272
|
+
async size() {
|
|
273
|
+
return this.readOp((tree) => tree.size());
|
|
274
|
+
}
|
|
275
|
+
async assertInvariants() {
|
|
276
|
+
await this.readOp((tree) => tree.assertInvariants());
|
|
277
|
+
}
|
|
278
|
+
async getStats() {
|
|
279
|
+
return this.readOp((tree) => tree.getStats());
|
|
280
|
+
}
|
|
281
|
+
async peekFirst() {
|
|
282
|
+
return this.readOp((tree) => tree.peekFirst());
|
|
283
|
+
}
|
|
284
|
+
async peekLast() {
|
|
285
|
+
return this.readOp((tree) => tree.peekLast());
|
|
286
|
+
}
|
|
287
|
+
async popLast() {
|
|
288
|
+
return this.runExclusive(async () => {
|
|
289
|
+
return this.appendMutationAndApplyUnlocked((tree) => {
|
|
290
|
+
return tree.peekLast() !== null ? { type: "popLast" } : null;
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
async peekById(entryId) {
|
|
295
|
+
return this.readOp((tree) => tree.peekById(entryId));
|
|
296
|
+
}
|
|
297
|
+
async count(startKey, endKey, options) {
|
|
298
|
+
return this.readOp((tree) => tree.count(startKey, endKey, options));
|
|
299
|
+
}
|
|
300
|
+
async nextHigherKey(key) {
|
|
301
|
+
return this.readOp((tree) => tree.nextHigherKey(key));
|
|
302
|
+
}
|
|
303
|
+
async nextLowerKey(key) {
|
|
304
|
+
return this.readOp((tree) => tree.nextLowerKey(key));
|
|
305
|
+
}
|
|
306
|
+
async getPairOrNextLower(key) {
|
|
307
|
+
return this.readOp((tree) => tree.getPairOrNextLower(key));
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
export {
|
|
311
|
+
BTreeConcurrencyError,
|
|
312
|
+
BTreeInvariantError,
|
|
313
|
+
BTreeValidationError,
|
|
314
|
+
ConcurrentInMemoryBTree,
|
|
315
|
+
InMemoryBTree
|
|
316
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@frostpillar/frostpillar-btree",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A tiny, zero-dependency in-memory B+ tree for TypeScript, Node.js, and browser JavaScript.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "Hajime Sano",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./core": {
|
|
16
|
+
"types": "./dist/core.d.ts",
|
|
17
|
+
"import": "./dist/core.js",
|
|
18
|
+
"require": "./dist/core.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/**/*.js",
|
|
24
|
+
"dist/**/*.cjs",
|
|
25
|
+
"dist/**/*.d.ts",
|
|
26
|
+
"README.md",
|
|
27
|
+
"README-JA.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"btree",
|
|
32
|
+
"b-plus-tree",
|
|
33
|
+
"in-memory",
|
|
34
|
+
"typescript",
|
|
35
|
+
"lightweight"
|
|
36
|
+
],
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/hjmsano/frostpillar-btree.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": "https://github.com/hjmsano/frostpillar-btree/issues",
|
|
43
|
+
"homepage": "https://github.com/hjmsano/frostpillar-btree#readme",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=24.0.0",
|
|
46
|
+
"pnpm": ">=10.0.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@eslint/js": "^10.0.1",
|
|
50
|
+
"@types/node": "^24.0.0",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
52
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
53
|
+
"esbuild": "^0.27.3",
|
|
54
|
+
"eslint": "^10.0.3",
|
|
55
|
+
"eslint-config-prettier": "^10.1.8",
|
|
56
|
+
"prettier": "^3.2.5",
|
|
57
|
+
"textlint": "^15.5.2",
|
|
58
|
+
"textlint-rule-preset-ja-technical-writing": "^12.0.2",
|
|
59
|
+
"typescript": "^5.9.3",
|
|
60
|
+
"typescript-eslint": "^8.56.1"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "rm -rf dist && pnpm build:esm && pnpm build:cjs && pnpm build:types",
|
|
64
|
+
"build:esm": "esbuild src/index.ts src/core.ts --bundle --splitting --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.bundle.json --outdir=dist",
|
|
65
|
+
"build:cjs": "esbuild src/index.ts src/core.ts --bundle --platform=node --format=cjs --target=es2022 --tsconfig=tsconfig.bundle.json --outdir=dist --out-extension:.js=.cjs",
|
|
66
|
+
"build:types": "tsc --project tsconfig.build.json",
|
|
67
|
+
"build:bundle": "esbuild src/index.ts --bundle --minify --target=es2020 --tsconfig=tsconfig.bundle.json --platform=browser --format=iife --global-name=FrostpillarBTree --outfile=dist/frostpillar-btree.min.js",
|
|
68
|
+
"build:bundle:core": "esbuild src/InMemoryBTree.ts --bundle --minify --target=es2020 --tsconfig=tsconfig.bundle.json --platform=browser --format=iife --global-name=FrostpillarBTreeCore --outfile=dist/frostpillar-btree-core.min.js",
|
|
69
|
+
"lint": "eslint .",
|
|
70
|
+
"format": "prettier --write .",
|
|
71
|
+
"textlint": "textlint \"**/*.md\"",
|
|
72
|
+
"textlint:fix": "textlint \"**/*.md\" --fix",
|
|
73
|
+
"format:md": "pnpm textlint:fix",
|
|
74
|
+
"check": "pnpm typecheck && pnpm lint && pnpm test && pnpm textlint",
|
|
75
|
+
"test": "node ./scripts/run-tests.mjs",
|
|
76
|
+
"test:coverage": "node ./scripts/run-tests.mjs --coverage",
|
|
77
|
+
"bench": "node ./scripts/run-benchmarks.mjs",
|
|
78
|
+
"typecheck": "tsc --project tsconfig.typecheck.json"
|
|
79
|
+
}
|
|
80
|
+
}
|