w-orm-lowdb 1.0.32 → 1.0.34
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/README.md +20 -3
- package/dist/w-orm-lowdb.umd.js +2 -2
- package/dist/w-orm-lowdb.umd.js.map +1 -1
- package/docs/WOrmLowdb.html +30 -17
- package/docs/WOrmLowdb.mjs.html +126 -6
- package/docs/index.html +1 -1
- package/package.json +3 -3
- package/src/WOrmLowdb.mjs +125 -5
- package/test/lib/leaves.mjs +46 -0
- package/test/lib/mkObserver.mjs +52 -0
- package/test/unit-date-write.test.mjs +711 -0
- package/test/unit-find-whitelist.test.mjs +433 -43
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
//呼叫端傳入物件之逐節點快照(unit-find-whitelist與unit-date-write共用, 只定義一處)
|
|
5
|
+
|
|
6
|
+
//timeOf, 以內部槽取Date之時間值, 非Date回傳undefined(跨realm、子類別、被改Symbol.toStringTag之Date皆可辨)
|
|
7
|
+
let timeOf = (v) => {
|
|
8
|
+
try {
|
|
9
|
+
return Date.prototype.getTime.call(v)
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
return undefined
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//leaves: 取物件之全部節點(物件節點記鍵序,Date節點記毫秒,皆記參照), 供reject後確認呼叫端實際傳入之同一物件逐節點未被改動; 物件須為無環
|
|
17
|
+
let leaves = (v, p = 'root', out = []) => {
|
|
18
|
+
let ms = timeOf(v)
|
|
19
|
+
if (ms !== undefined) {
|
|
20
|
+
out.push({ p, ref: v, ms })
|
|
21
|
+
}
|
|
22
|
+
else if (v !== null && typeof v === 'object') {
|
|
23
|
+
out.push({ p, ref: v, keys: Object.keys(v).join(',') })
|
|
24
|
+
for (let k of Object.keys(v)) {
|
|
25
|
+
leaves(v[k], `${p}.${k}`, out)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
out.push({ p, ref: v })
|
|
30
|
+
}
|
|
31
|
+
return out
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//chkSame: 兩次leaves之結果須逐節點相同(參照、毫秒、鍵序)
|
|
35
|
+
let chkSame = (a, b) => {
|
|
36
|
+
assert.strict.equal(a.length, b.length, 'object should keep the same number of nodes')
|
|
37
|
+
for (let i = 0; i < a.length; i++) {
|
|
38
|
+
assert.strict.equal(a[i].p, b[i].p)
|
|
39
|
+
assert.strict.equal(a[i].ref, b[i].ref, `${a[i].p} should keep the same reference or value`)
|
|
40
|
+
assert.strict.equal(a[i].ms, b[i].ms, `${a[i].p} should keep the same time value`)
|
|
41
|
+
assert.strict.equal(a[i].keys, b[i].keys, `${a[i].p} should keep the same keys`)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
export { timeOf, leaves, chkSame }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//呼叫觀測器(unit-find-whitelist與unit-date-write共用, 只定義一處)
|
|
2
|
+
|
|
3
|
+
//tick, 讓出一個macrotask, 令延遲發出之事件有機會發出
|
|
4
|
+
let tick = () => new Promise((resolve) => setTimeout(resolve, 0))
|
|
5
|
+
|
|
6
|
+
//mkObserver, 建立呼叫觀測器: 事件記錄於evs, 每筆error事件附帶發出當下呼叫端之await是否已恢復(settledAtEmit, 即呼叫端可觀察之先後)
|
|
7
|
+
let mkObserver = (wo) => {
|
|
8
|
+
let evs = []
|
|
9
|
+
let cur = { settled: false }
|
|
10
|
+
wo.on('error', function(mode, data, err) {
|
|
11
|
+
evs.push({ t: 'error', mode, data, err, settledAtEmit: cur.settled })
|
|
12
|
+
})
|
|
13
|
+
wo.on('change', function(mode) {
|
|
14
|
+
evs.push({ t: 'change', mode })
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
//run, 執行call()(回傳Promise之函數)並回傳{ ok, val, err, nAtSettle, probe, evs }, nAtSettle為結果定案當下之事件數,
|
|
18
|
+
//probe為結果定案當下(同一microtask鏈內, 尚未讓出macrotask)呼叫probeFn()之回傳, evs為再讓出一個macrotask後之事件
|
|
19
|
+
let run = async(call, probeFn = null) => {
|
|
20
|
+
evs.length = 0
|
|
21
|
+
cur = { settled: false }
|
|
22
|
+
let out = { ok: false, val: null, err: null, nAtSettle: 0, probe: null, evs: [] }
|
|
23
|
+
try {
|
|
24
|
+
out.val = await call()
|
|
25
|
+
out.ok = true
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
out.err = err
|
|
29
|
+
}
|
|
30
|
+
cur.settled = true
|
|
31
|
+
out.nAtSettle = evs.length
|
|
32
|
+
out.probe = probeFn ? probeFn() : null
|
|
33
|
+
await tick()
|
|
34
|
+
out.evs = evs.slice()
|
|
35
|
+
return out
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//invoke, 呼叫wo[fn](arg)
|
|
39
|
+
let invoke = (fn, arg, probeFn = null) => {
|
|
40
|
+
return run(() => wo[fn](arg), probeFn)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//clear
|
|
44
|
+
let clear = () => {
|
|
45
|
+
evs.length = 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { run, invoke, clear }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export { tick, mkObserver }
|