@mblaney/holster 1.0.35 → 2.0.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/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/dist/holster.js +4 -0
- package/dist/holster.js.map +7 -0
- package/package.json +22 -5
- package/src/dup.js +4 -5
- package/src/get.js +10 -19
- package/src/ham.js +22 -49
- package/src/holster.js +172 -58
- package/src/index.js +1 -1
- package/src/radisk.js +89 -86
- package/src/sea-utils.js +1 -1
- package/src/sea.js +0 -52
- package/src/store.js +8 -8
- package/src/user.js +0 -4
- package/src/wire.js +209 -79
- package/ts/src/array.ts +78 -0
- package/ts/src/buffer.ts +441 -0
- package/ts/src/dup.ts +38 -0
- package/ts/src/get.ts +83 -0
- package/ts/src/ham.ts +258 -0
- package/ts/src/holster.ts +968 -0
- package/ts/src/index.ts +35 -0
- package/ts/src/radisk.ts +591 -0
- package/ts/src/radix.ts +157 -0
- package/ts/src/schemas.ts +515 -0
- package/ts/src/sea-utils.ts +103 -0
- package/ts/src/sea.ts +388 -0
- package/ts/src/store.ts +321 -0
- package/ts/src/user.ts +377 -0
- package/ts/src/utils.ts +232 -0
- package/ts/src/wire.ts +961 -0
- package/.dockerignore +0 -9
- package/.github/workflows/node.js.yml +0 -31
- package/.github/workflows/npm-publish.yml +0 -33
- package/Dockerfile +0 -20
- package/examples/index.html +0 -33
- package/examples/index.js +0 -49
- package/examples/user.html +0 -31
- package/examples/user.js +0 -93
- package/examples/wire.html +0 -27
- package/examples/wire.js +0 -55
- package/test/holster.get.test.js +0 -94
- package/test/holster.lex.test.js +0 -196
- package/test/holster.off.test.js +0 -53
- package/test/holster.on.test.js +0 -264
- package/test/holster.put.test.js +0 -358
- package/test/holster.secure.test.js +0 -202
- package/test/holster.user.get.test.js +0 -114
- package/test/holster.user.lex.test.js +0 -149
- package/test/holster.user.off.test.js +0 -73
- package/test/holster.user.on.test.js +0 -300
- package/test/holster.user.put.test.js +0 -463
- package/test/kitty/! +0 -9
- package/test/names.js +0 -225
- package/test/radisk.cache.test.js +0 -213
- package/test/radisk.test.js +0 -331
- package/test/radix.test.js +0 -117
- package/test/sea.test.js +0 -284
- package/test/split.test.js +0 -317
- package/test/store.test.js +0 -316
- package/test/system/basic.test.js +0 -29
- package/test/system/chained-on.test.js +0 -41
- package/test/system/concurrent-listeners.test.js +0 -125
- package/test/system/immediate-read.test.js +0 -30
- package/test/system/listener-before-data.test.js +0 -51
- package/test/system/promise-wrapper.test.js +0 -47
- package/test/system/user-chained-on.test.js +0 -60
- package/test/system/user-concurrent-listeners.test.js +0 -142
- package/test/system/user-listener-before-data.test.js +0 -66
- package/test/user.test.js +0 -173
- package/test/wire.test.js +0 -158
package/test/store.test.js
DELETED
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
import {describe, test} from "node:test"
|
|
2
|
-
import assert from "node:assert/strict"
|
|
3
|
-
import Store from "../src/store.js"
|
|
4
|
-
import fs from "fs"
|
|
5
|
-
|
|
6
|
-
describe("store", () => {
|
|
7
|
-
const kitty = Store({file: "test/kitty"})
|
|
8
|
-
const multiple = Store({file: "test/multiple", size: 100})
|
|
9
|
-
const special = Store({file: "test/special"})
|
|
10
|
-
const newFileValue =
|
|
11
|
-
"file size is only 100 bytes so writing this value requires calling slice"
|
|
12
|
-
|
|
13
|
-
test("get graph", (t, done) => {
|
|
14
|
-
kitty.get({"#": "FDSA"}, (err, value) => {
|
|
15
|
-
assert.deepEqual(value, {
|
|
16
|
-
FDSA: {
|
|
17
|
-
_: {
|
|
18
|
-
"#": "FDSA",
|
|
19
|
-
">": {
|
|
20
|
-
color: 3,
|
|
21
|
-
name: 2,
|
|
22
|
-
slave: 2,
|
|
23
|
-
species: 2,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
color: "ginger",
|
|
27
|
-
name: "Fluffy",
|
|
28
|
-
slave: {
|
|
29
|
-
"#": "ASDF",
|
|
30
|
-
},
|
|
31
|
-
species: "felis silvestris",
|
|
32
|
-
},
|
|
33
|
-
})
|
|
34
|
-
done()
|
|
35
|
-
})
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test("get item", (t, done) => {
|
|
39
|
-
kitty.get({"#": "FDSA", ".": "species"}, (err, value) => {
|
|
40
|
-
assert.deepEqual(value, {
|
|
41
|
-
FDSA: {
|
|
42
|
-
_: {
|
|
43
|
-
"#": "FDSA",
|
|
44
|
-
">": {
|
|
45
|
-
species: 2,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
species: "felis silvestris",
|
|
49
|
-
},
|
|
50
|
-
})
|
|
51
|
-
done()
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test("put keys to multiple files", (t, done) => {
|
|
56
|
-
multiple.put(
|
|
57
|
-
{
|
|
58
|
-
keyA: {
|
|
59
|
-
_: {"#": "keyA", ">": {value: 1}},
|
|
60
|
-
value: "valueA",
|
|
61
|
-
},
|
|
62
|
-
keyB: {
|
|
63
|
-
_: {"#": "keyB", ">": {value: 1}},
|
|
64
|
-
value: "valueB",
|
|
65
|
-
},
|
|
66
|
-
keyC: {
|
|
67
|
-
_: {"#": "keyC", ">": {value: 1, extraField: 1}},
|
|
68
|
-
value: "valueC",
|
|
69
|
-
extraField: true,
|
|
70
|
-
},
|
|
71
|
-
newFile: {
|
|
72
|
-
_: {"#": "newFile", ">": {value: 1}},
|
|
73
|
-
value: newFileValue,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
err => {
|
|
77
|
-
assert.equal(err, null)
|
|
78
|
-
fs.access("test/multiple/!", err => {
|
|
79
|
-
assert.equal(err, null)
|
|
80
|
-
fs.access("test/multiple/newFile", err => {
|
|
81
|
-
assert.equal(err, null)
|
|
82
|
-
done()
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
},
|
|
86
|
-
)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
test("get key from first file", (t, done) => {
|
|
90
|
-
multiple.get({"#": "keyA"}, (err, value) => {
|
|
91
|
-
assert.deepEqual(value, {
|
|
92
|
-
keyA: {
|
|
93
|
-
_: {
|
|
94
|
-
"#": "keyA",
|
|
95
|
-
">": {
|
|
96
|
-
value: 1,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
value: "valueA",
|
|
100
|
-
},
|
|
101
|
-
})
|
|
102
|
-
done()
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
test("get another key from first file", (t, done) => {
|
|
107
|
-
multiple.get({"#": "keyC"}, (err, value) => {
|
|
108
|
-
assert.deepEqual(value, {
|
|
109
|
-
keyC: {
|
|
110
|
-
_: {
|
|
111
|
-
"#": "keyC",
|
|
112
|
-
">": {
|
|
113
|
-
extraField: 1,
|
|
114
|
-
value: 1,
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
extraField: true,
|
|
118
|
-
value: "valueC",
|
|
119
|
-
},
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
multiple.get({"#": "keyC", ".": "value"}, (err, value) => {
|
|
123
|
-
assert.deepEqual(value, {
|
|
124
|
-
keyC: {
|
|
125
|
-
_: {
|
|
126
|
-
"#": "keyC",
|
|
127
|
-
">": {
|
|
128
|
-
value: 1,
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
value: "valueC",
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
done()
|
|
135
|
-
})
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
test("get key from second file", (t, done) => {
|
|
139
|
-
multiple.get({"#": "newFile"}, (err, value) => {
|
|
140
|
-
assert.deepEqual(value, {
|
|
141
|
-
newFile: {
|
|
142
|
-
_: {
|
|
143
|
-
"#": "newFile",
|
|
144
|
-
">": {
|
|
145
|
-
value: 1,
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
value: newFileValue,
|
|
149
|
-
},
|
|
150
|
-
})
|
|
151
|
-
fs.rm("test/multiple", {recursive: true, force: true}, err => {
|
|
152
|
-
assert.equal(err, null)
|
|
153
|
-
done()
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
test("put keys with special characters", (t, done) => {
|
|
159
|
-
special.put(
|
|
160
|
-
{
|
|
161
|
-
"#": {
|
|
162
|
-
_: {"#": "#", ">": {value: 1}},
|
|
163
|
-
value: "ok got #",
|
|
164
|
-
},
|
|
165
|
-
">": {
|
|
166
|
-
_: {"#": ">", ">": {value: 1, extraField: 1}},
|
|
167
|
-
value: "ok got >",
|
|
168
|
-
extraField: true,
|
|
169
|
-
},
|
|
170
|
-
".": {
|
|
171
|
-
_: {"#": ".", ">": {value: 1, extraField: 1}},
|
|
172
|
-
value: "ok got .",
|
|
173
|
-
extraField: true,
|
|
174
|
-
},
|
|
175
|
-
"+": {
|
|
176
|
-
_: {"#": "+", ">": {value: 1}},
|
|
177
|
-
value: "ok got +",
|
|
178
|
-
},
|
|
179
|
-
"[": {
|
|
180
|
-
_: {"#": "[", ">": {value: 1}},
|
|
181
|
-
value: "ok got [",
|
|
182
|
-
},
|
|
183
|
-
",": {
|
|
184
|
-
_: {"#": ",", ">": {value: 1}},
|
|
185
|
-
value: "ok got ,",
|
|
186
|
-
},
|
|
187
|
-
'"': {
|
|
188
|
-
_: {"#": '"', ">": {value: 1}},
|
|
189
|
-
value: 'ok got "',
|
|
190
|
-
},
|
|
191
|
-
_: {
|
|
192
|
-
_: {"#": "_", ">": {value: 1}},
|
|
193
|
-
value: "ok got _",
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
err => {
|
|
197
|
-
assert.equal(err, null)
|
|
198
|
-
fs.access("test/special/!", err => {
|
|
199
|
-
assert.equal(err, null)
|
|
200
|
-
done()
|
|
201
|
-
})
|
|
202
|
-
},
|
|
203
|
-
)
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
test("get keys with special characters", (t, done) => {
|
|
207
|
-
special.get({"#": "#"}, (err, value) => {
|
|
208
|
-
assert.deepEqual(value, {
|
|
209
|
-
"#": {
|
|
210
|
-
_: {
|
|
211
|
-
"#": "#",
|
|
212
|
-
">": {
|
|
213
|
-
value: 1,
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
value: "ok got #",
|
|
217
|
-
},
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
special.get({"#": ">", ".": "value"}, (err, value) => {
|
|
221
|
-
assert.deepEqual(value, {
|
|
222
|
-
">": {
|
|
223
|
-
_: {
|
|
224
|
-
"#": ">",
|
|
225
|
-
">": {
|
|
226
|
-
value: 1,
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
value: "ok got >",
|
|
230
|
-
},
|
|
231
|
-
})
|
|
232
|
-
})
|
|
233
|
-
special.get({"#": ".", ".": "value"}, (err, value) => {
|
|
234
|
-
assert.deepEqual(value, {
|
|
235
|
-
".": {
|
|
236
|
-
_: {
|
|
237
|
-
"#": ".",
|
|
238
|
-
">": {
|
|
239
|
-
value: 1,
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
value: "ok got .",
|
|
243
|
-
},
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
special.get({"#": "+"}, (err, value) => {
|
|
247
|
-
assert.deepEqual(value, {
|
|
248
|
-
"+": {
|
|
249
|
-
_: {
|
|
250
|
-
"#": "+",
|
|
251
|
-
">": {
|
|
252
|
-
value: 1,
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
value: "ok got +",
|
|
256
|
-
},
|
|
257
|
-
})
|
|
258
|
-
})
|
|
259
|
-
special.get({"#": "["}, (err, value) => {
|
|
260
|
-
assert.deepEqual(value, {
|
|
261
|
-
"[": {
|
|
262
|
-
_: {
|
|
263
|
-
"#": "[",
|
|
264
|
-
">": {
|
|
265
|
-
value: 1,
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
value: "ok got [",
|
|
269
|
-
},
|
|
270
|
-
})
|
|
271
|
-
})
|
|
272
|
-
special.get({"#": ","}, (err, value) => {
|
|
273
|
-
assert.deepEqual(value, {
|
|
274
|
-
",": {
|
|
275
|
-
_: {
|
|
276
|
-
"#": ",",
|
|
277
|
-
">": {
|
|
278
|
-
value: 1,
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
|
-
value: "ok got ,",
|
|
282
|
-
},
|
|
283
|
-
})
|
|
284
|
-
})
|
|
285
|
-
special.get({"#": '"'}, (err, value) => {
|
|
286
|
-
assert.deepEqual(value, {
|
|
287
|
-
'"': {
|
|
288
|
-
_: {
|
|
289
|
-
"#": '"',
|
|
290
|
-
">": {
|
|
291
|
-
value: 1,
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
value: 'ok got "',
|
|
295
|
-
},
|
|
296
|
-
})
|
|
297
|
-
})
|
|
298
|
-
special.get({"#": "_"}, (err, value) => {
|
|
299
|
-
assert.deepEqual(value, {
|
|
300
|
-
_: {
|
|
301
|
-
_: {
|
|
302
|
-
"#": "_",
|
|
303
|
-
">": {
|
|
304
|
-
value: 1,
|
|
305
|
-
},
|
|
306
|
-
},
|
|
307
|
-
value: "ok got _",
|
|
308
|
-
},
|
|
309
|
-
})
|
|
310
|
-
fs.rm("test/special", {recursive: true, force: true}, err => {
|
|
311
|
-
assert.equal(err, null)
|
|
312
|
-
done()
|
|
313
|
-
})
|
|
314
|
-
})
|
|
315
|
-
})
|
|
316
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - basic setup", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9001")
|
|
9
|
-
const holster = Holster({file: "test/system/basic", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("put and get data", (t, done) => {
|
|
12
|
-
holster.get("test").put({message: "hello"}, err => {
|
|
13
|
-
assert.equal(err, null)
|
|
14
|
-
|
|
15
|
-
holster.get("test", data => {
|
|
16
|
-
assert.notEqual(data, null)
|
|
17
|
-
assert.equal(data.message, "hello")
|
|
18
|
-
done()
|
|
19
|
-
})
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test("cleanup", (t, done) => {
|
|
24
|
-
fs.rm("test/system/basic", {recursive: true, force: true}, err => {
|
|
25
|
-
assert.equal(err, null)
|
|
26
|
-
done()
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
})
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - chained get with on", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9002")
|
|
9
|
-
const holster = Holster({file: "test/system/chained-on", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("on listener fires with null when no data exists", (t, done) => {
|
|
12
|
-
holster.get("key").on(data => {
|
|
13
|
-
// This is the actual behavior - on fires with null for non-existent keys
|
|
14
|
-
assert.equal(data, null)
|
|
15
|
-
done()
|
|
16
|
-
}, true)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test("put then on listener receives data", (t, done) => {
|
|
20
|
-
// Put data first
|
|
21
|
-
holster.get("key2").put({value: "test"}, err => {
|
|
22
|
-
assert.equal(err, null)
|
|
23
|
-
|
|
24
|
-
// Then set up listener - should get the existing data
|
|
25
|
-
setTimeout(() => {
|
|
26
|
-
holster.get("key2").on(data => {
|
|
27
|
-
assert.notEqual(data, null)
|
|
28
|
-
assert.equal(data.value, "test")
|
|
29
|
-
done()
|
|
30
|
-
}, true)
|
|
31
|
-
}, 50)
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test("cleanup", (t, done) => {
|
|
36
|
-
fs.rm("test/system/chained-on", {recursive: true, force: true}, err => {
|
|
37
|
-
assert.equal(err, null)
|
|
38
|
-
done()
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
})
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - concurrent listeners", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9005")
|
|
9
|
-
const holster = Holster({file: "test/system/concurrent-listeners", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("multiple listeners on same path receive data", (t, done) => {
|
|
12
|
-
let listener1Called = false
|
|
13
|
-
let listener2Called = false
|
|
14
|
-
|
|
15
|
-
holster.get("key").put({value: "test"}, err => {
|
|
16
|
-
assert.equal(err, null)
|
|
17
|
-
|
|
18
|
-
// Set up two listeners on the same path
|
|
19
|
-
holster.get("key").on(data => {
|
|
20
|
-
listener1Called = true
|
|
21
|
-
assert.notEqual(data, null)
|
|
22
|
-
assert.equal(data.value, "test")
|
|
23
|
-
checkComplete()
|
|
24
|
-
}, true)
|
|
25
|
-
|
|
26
|
-
holster.get("key").on(data => {
|
|
27
|
-
listener2Called = true
|
|
28
|
-
assert.notEqual(data, null)
|
|
29
|
-
assert.equal(data.value, "test")
|
|
30
|
-
checkComplete()
|
|
31
|
-
}, true)
|
|
32
|
-
|
|
33
|
-
function checkComplete() {
|
|
34
|
-
if (listener1Called && listener2Called) {
|
|
35
|
-
done()
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test("nested listeners on parent and child paths", (t, done) => {
|
|
42
|
-
let parentCalled = false
|
|
43
|
-
let childCalled = false
|
|
44
|
-
|
|
45
|
-
holster.get("parent").put({value: "parent-value"}, err => {
|
|
46
|
-
assert.equal(err, null)
|
|
47
|
-
|
|
48
|
-
holster
|
|
49
|
-
.get("parent")
|
|
50
|
-
.next("child")
|
|
51
|
-
.put({value: "child-value"}, err => {
|
|
52
|
-
assert.equal(err, null)
|
|
53
|
-
|
|
54
|
-
// Listen on parent
|
|
55
|
-
holster.get("parent").on(data => {
|
|
56
|
-
parentCalled = true
|
|
57
|
-
assert.notEqual(data, null)
|
|
58
|
-
assert.equal(data.value, "parent-value")
|
|
59
|
-
checkComplete()
|
|
60
|
-
}, true)
|
|
61
|
-
|
|
62
|
-
// Listen on child
|
|
63
|
-
holster
|
|
64
|
-
.get("parent")
|
|
65
|
-
.next("child")
|
|
66
|
-
.on(data => {
|
|
67
|
-
childCalled = true
|
|
68
|
-
assert.notEqual(data, null)
|
|
69
|
-
assert.equal(data.value, "child-value")
|
|
70
|
-
checkComplete()
|
|
71
|
-
}, true)
|
|
72
|
-
|
|
73
|
-
function checkComplete() {
|
|
74
|
-
if (parentCalled && childCalled) {
|
|
75
|
-
done()
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
test("listener race condition - data before and after listener setup", (t, done) => {
|
|
83
|
-
const results = []
|
|
84
|
-
|
|
85
|
-
// Put data first
|
|
86
|
-
holster.get("race").put({value: "first"}, err => {
|
|
87
|
-
assert.equal(err, null)
|
|
88
|
-
|
|
89
|
-
// Set up listener with _get=true to read existing data
|
|
90
|
-
// The listener will be called with the existing data via the get request
|
|
91
|
-
holster.get("race").on(data => {
|
|
92
|
-
results.push(data?.value)
|
|
93
|
-
}, true)
|
|
94
|
-
|
|
95
|
-
// Immediately put new data - listener will fire for this put as well
|
|
96
|
-
setTimeout(() => {
|
|
97
|
-
holster.get("race").put({value: "second"}, err => {
|
|
98
|
-
assert.equal(err, null)
|
|
99
|
-
|
|
100
|
-
setTimeout(() => {
|
|
101
|
-
// Should have received both values - one from get, one from put
|
|
102
|
-
assert.equal(
|
|
103
|
-
results.length >= 1,
|
|
104
|
-
true,
|
|
105
|
-
"Should receive at least initial value from get",
|
|
106
|
-
)
|
|
107
|
-
assert.equal(results[0], "first", "First value should be 'first'")
|
|
108
|
-
done()
|
|
109
|
-
}, 100)
|
|
110
|
-
})
|
|
111
|
-
}, 50)
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
test("cleanup", (t, done) => {
|
|
116
|
-
fs.rm(
|
|
117
|
-
"test/system/concurrent-listeners",
|
|
118
|
-
{recursive: true, force: true},
|
|
119
|
-
err => {
|
|
120
|
-
assert.equal(err, null)
|
|
121
|
-
done()
|
|
122
|
-
},
|
|
123
|
-
)
|
|
124
|
-
})
|
|
125
|
-
})
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - immediate read after write", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9008")
|
|
9
|
-
const holster = Holster({file: "test/system/immediate-read", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("get immediately after put returns data despite queue delays", (t, done) => {
|
|
12
|
-
holster.get("testkey").put({value: "test"}, err => {
|
|
13
|
-
assert.equal(err, null)
|
|
14
|
-
|
|
15
|
-
// Immediate get after put - validates retry logic handles queued writes
|
|
16
|
-
holster.get("testkey", data => {
|
|
17
|
-
assert.notEqual(data, null)
|
|
18
|
-
assert.equal(data.value, "test")
|
|
19
|
-
done()
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
test("cleanup", (t, done) => {
|
|
25
|
-
fs.rm("test/system/immediate-read", {recursive: true, force: true}, err => {
|
|
26
|
-
assert.equal(err, null)
|
|
27
|
-
done()
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
})
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - listener before data", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9007")
|
|
9
|
-
const holster = Holster({file: "test/system/listener-before-data", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("listener set up before data exists receives data when populated", (t, done) => {
|
|
12
|
-
const results = []
|
|
13
|
-
|
|
14
|
-
// Set up listener first - this is the browser Display.js pattern
|
|
15
|
-
holster.get("testkey").on(data => {
|
|
16
|
-
results.push(data)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
// Give listener time to set up
|
|
20
|
-
setTimeout(() => {
|
|
21
|
-
holster.get("testkey").put({value: "test"}, err => {
|
|
22
|
-
assert.equal(err, null)
|
|
23
|
-
|
|
24
|
-
// Give listener time to fire
|
|
25
|
-
setTimeout(() => {
|
|
26
|
-
// With the new behavior, listener fires after data is stored
|
|
27
|
-
// Should have received the test value from the put
|
|
28
|
-
const nonNull = results.filter(r => r !== null)
|
|
29
|
-
assert.equal(
|
|
30
|
-
nonNull.length >= 1,
|
|
31
|
-
true,
|
|
32
|
-
"Should have at least one non-null result",
|
|
33
|
-
)
|
|
34
|
-
assert.equal(nonNull[0].value, "test")
|
|
35
|
-
done()
|
|
36
|
-
}, 200)
|
|
37
|
-
})
|
|
38
|
-
}, 100)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test("cleanup", (t, done) => {
|
|
42
|
-
fs.rm(
|
|
43
|
-
"test/system/listener-before-data",
|
|
44
|
-
{recursive: true, force: true},
|
|
45
|
-
err => {
|
|
46
|
-
assert.equal(err, null)
|
|
47
|
-
done()
|
|
48
|
-
},
|
|
49
|
-
)
|
|
50
|
-
})
|
|
51
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - promise wrapped calls", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9004")
|
|
9
|
-
const holster = Holster({file: "test/system/promise-wrapper", wss: wss})
|
|
10
|
-
|
|
11
|
-
test("promise wrapped get returns null for missing key", async t => {
|
|
12
|
-
const data = await new Promise(res => {
|
|
13
|
-
holster.get("missing", res)
|
|
14
|
-
})
|
|
15
|
-
assert.equal(data, null)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test("promise wrapped get returns data for existing key", async t => {
|
|
19
|
-
await new Promise(res => {
|
|
20
|
-
holster.get("key").put({value: "test"}, res)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const data = await new Promise(res => {
|
|
24
|
-
holster.get("key", res)
|
|
25
|
-
})
|
|
26
|
-
assert.notEqual(data, null)
|
|
27
|
-
assert.equal(data.value, "test")
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test("promise wrapped next returns null for missing nested key", async t => {
|
|
31
|
-
const data = await new Promise(res => {
|
|
32
|
-
holster.get("key1").next("missing", res)
|
|
33
|
-
})
|
|
34
|
-
assert.equal(data, null)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test("cleanup", (t, done) => {
|
|
38
|
-
fs.rm(
|
|
39
|
-
"test/system/promise-wrapper",
|
|
40
|
-
{recursive: true, force: true},
|
|
41
|
-
err => {
|
|
42
|
-
assert.equal(err, null)
|
|
43
|
-
done()
|
|
44
|
-
},
|
|
45
|
-
)
|
|
46
|
-
})
|
|
47
|
-
})
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import fs from "fs"
|
|
2
|
-
import {Server} from "mock-socket"
|
|
3
|
-
import {describe, test} from "node:test"
|
|
4
|
-
import assert from "node:assert/strict"
|
|
5
|
-
import Holster from "../../src/holster.js"
|
|
6
|
-
|
|
7
|
-
describe("system - user chained get with on", () => {
|
|
8
|
-
const wss = new Server("ws://localhost:9012")
|
|
9
|
-
const holster = Holster({
|
|
10
|
-
file: "test/system/user-chained-on",
|
|
11
|
-
wss: wss,
|
|
12
|
-
wait: 500,
|
|
13
|
-
})
|
|
14
|
-
const user = holster.user()
|
|
15
|
-
|
|
16
|
-
test("user create and auth", (t, done) => {
|
|
17
|
-
user.create("testuser", "password", err => {
|
|
18
|
-
assert.equal(err, null)
|
|
19
|
-
user.auth("testuser", "password", err => {
|
|
20
|
-
assert.equal(err, null)
|
|
21
|
-
done()
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
test("on listener fires with null when no data exists", (t, done) => {
|
|
27
|
-
user.get("key").on(data => {
|
|
28
|
-
// This is the actual behavior - on fires with null for non-existent keys
|
|
29
|
-
assert.equal(data, null)
|
|
30
|
-
done()
|
|
31
|
-
}, true)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
test("put then on listener receives data", (t, done) => {
|
|
35
|
-
// Put data first
|
|
36
|
-
user.get("key2").put({value: "test"}, err => {
|
|
37
|
-
assert.equal(err, null)
|
|
38
|
-
|
|
39
|
-
// Then set up listener - should get the existing data
|
|
40
|
-
setTimeout(() => {
|
|
41
|
-
user.get("key2").on(data => {
|
|
42
|
-
assert.notEqual(data, null)
|
|
43
|
-
assert.deepEqual(data, {value: "test"})
|
|
44
|
-
done()
|
|
45
|
-
}, true)
|
|
46
|
-
}, 50)
|
|
47
|
-
})
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test("cleanup", (t, done) => {
|
|
51
|
-
fs.rm(
|
|
52
|
-
"test/system/user-chained-on",
|
|
53
|
-
{recursive: true, force: true},
|
|
54
|
-
err => {
|
|
55
|
-
assert.equal(err, null)
|
|
56
|
-
done()
|
|
57
|
-
},
|
|
58
|
-
)
|
|
59
|
-
})
|
|
60
|
-
})
|