corebasic 1.0.230 → 1.0.232
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/dist/libs/auth.js +5 -4
- package/dist/libs/compression.js +1 -7
- package/dist/libs/dip/suffix/index.js +8 -6
- package/dist/libs/dip/suffix/policy.js +6 -4
- package/dist/libs/dip/suffix/query.js +290 -279
- package/dist/libs/dip/suffix/suffix.js +17 -13
- package/dist/libs/dip/suffix/tests/date.test.js +21 -34
- package/dist/libs/dip/suffix/tests/policy.test.js +41 -80
- package/dist/libs/dip.js +29 -26
- package/dist/libs/dipper.js +0 -1
- package/dist/libs/elabase.js +1 -1
- package/dist/libs/features.js +110 -60
- package/dist/libs/kafka.js +6 -5
- package/dist/libs/messaging.js +7 -4
- package/dist/libs/session.js +2 -2
- package/libs/auth.ts +48 -9
- package/libs/compression.ts +6 -1
- package/libs/cpp.ts +15 -13
- package/libs/dip/suffix/date.ts +6 -6
- package/libs/dip/suffix/index.ts +41 -26
- package/libs/dip/suffix/policy.ts +16 -13
- package/libs/dip/suffix/query.ts +289 -289
- package/libs/dip/suffix/suffix.ts +26 -20
- package/libs/dip/suffix/tests/date.test.ts +32 -64
- package/libs/dip/suffix/tests/policy.applySuffixPolicy.test.ts +20 -20
- package/libs/dip/suffix/tests/policy.test.ts +41 -109
- package/libs/dip/suffix/tests/suffix.test.ts +2 -2
- package/libs/dip.ts +61 -33
- package/libs/dipper.ts +25 -10
- package/libs/elabase.ts +1 -1
- package/libs/features.ts +232 -95
- package/libs/kafka.ts +75 -14
- package/libs/messaging.ts +80 -19
- package/libs/session.ts +21 -10
- package/package.json +1 -1
|
@@ -8,11 +8,16 @@ export async function suffix(doc, policies, insertMode, arg) {
|
|
|
8
8
|
const value = typeof policy.value === "string" ? policy.value.trim() : undefined;
|
|
9
9
|
if ("value" in policy && !value)
|
|
10
10
|
throw new Error(`Error: Invalid suffix policy fixed 'value' specified for key in Dip`);
|
|
11
|
-
let
|
|
12
|
-
const [policy_type,
|
|
11
|
+
let candidates = value ? [value] : entries(policy.key ?? '', doc);
|
|
12
|
+
const [policy_type, format_type] = (policy.type ?? "string").split(':');
|
|
13
|
+
const format = format_type ?? "";
|
|
13
14
|
if (!EXPLICIT_SUFFIX_POLICY_TYPES.has(policy_type))
|
|
14
15
|
throw new Error(`Error: Invalid suffix policy type specified for key ${policy.key} in Dip`);
|
|
15
|
-
|
|
16
|
+
// ====== Range ======
|
|
17
|
+
let ranges = candidates.filter(item => typeof item === "object");
|
|
18
|
+
let keys = candidates.filter(item => typeof item !== "object");
|
|
19
|
+
// ====== Range ======
|
|
20
|
+
if (policy_type === "string" && ranges.length)
|
|
16
21
|
throw new Error(`Error: Invalid numeric bounds on string type in suffix policy specified for key ${policy.key} in Dip`);
|
|
17
22
|
if (policy_type === "date") {
|
|
18
23
|
if (!format?.trim())
|
|
@@ -22,14 +27,12 @@ export async function suffix(doc, policies, insertMode, arg) {
|
|
|
22
27
|
}
|
|
23
28
|
const ls_threshold = policy.ls_threshold ?? 5000;
|
|
24
29
|
// ====== Range ======
|
|
25
|
-
let ranges = keys.filter(item => typeof item === "object");
|
|
26
|
-
keys = keys.filter(item => typeof item !== "object");
|
|
27
30
|
if (policy_type === "date") {
|
|
28
31
|
keys = keys.map(key => formatDate(key, format));
|
|
29
32
|
if (ranges.length) {
|
|
30
33
|
const bounds = extractBounds(reduceRanges(ranges));
|
|
31
|
-
const from = bounds.from ?? policy.min; // policy.min is always inclusive i.e $gte
|
|
32
|
-
const to = bounds.to ?? policy.max; // policy.max is always inclusive i.e $lte
|
|
34
|
+
const from = (bounds.from ?? policy.min); // policy.min is always inclusive i.e $gte
|
|
35
|
+
const to = (bounds.to ?? policy.max); // policy.max is always inclusive i.e $lte
|
|
33
36
|
const fromOp = bounds.from ? bounds.fromOp : "$gte"; // policy.min is $gte
|
|
34
37
|
const toOp = bounds.to ? bounds.toOp : "$lte"; // policy.max is $lte
|
|
35
38
|
if (from === undefined || to === undefined) {
|
|
@@ -38,8 +41,8 @@ export async function suffix(doc, policies, insertMode, arg) {
|
|
|
38
41
|
}
|
|
39
42
|
else {
|
|
40
43
|
let ranges = fillDates({ from, to, fromOp, toOp }, format);
|
|
41
|
-
if (!ranges.length && policy.inferRange)
|
|
42
|
-
|
|
44
|
+
// if (!ranges.length && policy.inferRange)
|
|
45
|
+
// ranges = [...new Set([from === undefined ? undefined : formatDate(from, format), to === undefined ? undefined : formatDate(to, format)].filter(item => item))]
|
|
43
46
|
// console.log(ranges)
|
|
44
47
|
if (ranges.length > ls_threshold) {
|
|
45
48
|
keys = []; // Too many suffixes to enumerate. Fall back to Dip.operation("ls").
|
|
@@ -53,8 +56,8 @@ export async function suffix(doc, policies, insertMode, arg) {
|
|
|
53
56
|
}
|
|
54
57
|
else if (policy_type === "number" && ranges.length) {
|
|
55
58
|
const bounds = getNormalizedBounds(extractBounds(reduceRanges(ranges)), "number");
|
|
56
|
-
const from = bounds.from ?? policy.min; // policy.min is always inclusive i.e $gte
|
|
57
|
-
const to = bounds.to ?? policy.max; // policy.max is always inclusive i.e $lte
|
|
59
|
+
const from = (bounds.from ?? policy.min); // policy.min is always inclusive i.e $gte
|
|
60
|
+
const to = (bounds.to ?? policy.max); // policy.max is always inclusive i.e $lte
|
|
58
61
|
if (from === undefined || to === undefined) {
|
|
59
62
|
keys = []; // Fall back to Dip.operation("ls").
|
|
60
63
|
console.warn(`Warn: Missing suffix policy min/max bound for ${policy_type} range specified for key ${policy.key} in Dip`);
|
|
@@ -79,8 +82,9 @@ export async function suffix(doc, policies, insertMode, arg) {
|
|
|
79
82
|
if (!keys.length && !insertMode) {
|
|
80
83
|
ls = true;
|
|
81
84
|
for (const suffix of suffixes) {
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
const collections = arg?.collection ?? [];
|
|
86
|
+
for (const collection of collections) {
|
|
87
|
+
const dirs = (await Dip.operation("ls", { db: arg?.db, collection: collection, suffix })).filter((dir) => !dir.startsWith('chunk-'));
|
|
84
88
|
suffixAssociatedKeys[suffix] = suffixAssociatedKeys[suffix] ?? [];
|
|
85
89
|
suffixAssociatedKeys[suffix].push(...dirs);
|
|
86
90
|
}
|
|
@@ -142,46 +142,33 @@ describe("fillDates()", () => {
|
|
|
142
142
|
const result = fillDates({ from: "2026-01-01", to: "2026-12-31", fromOp: "$gte", toOp: "$lte" }, "YYYY-MM-DD");
|
|
143
143
|
assert.equal(new Set(result).size, result.length);
|
|
144
144
|
});
|
|
145
|
-
test("excludes lower bound with $gt", () => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"2026-07-02",
|
|
165
|
-
]);
|
|
166
|
-
});
|
|
145
|
+
// test("excludes lower bound with $gt", () => {
|
|
146
|
+
// assert.deepEqual(
|
|
147
|
+
// fillDates({ from: "2026-07-01", to: "2026-07-03", fromOp: "$gt", toOp: null }, "YYYY-MM-DD"),
|
|
148
|
+
// [
|
|
149
|
+
// "2026-07-02",
|
|
150
|
+
// "2026-07-03",
|
|
151
|
+
// ]
|
|
152
|
+
// );
|
|
153
|
+
// });
|
|
154
|
+
//
|
|
155
|
+
// test("excludes upper bound with $lt", () => {
|
|
156
|
+
// assert.deepEqual(
|
|
157
|
+
// fillDates({ from: "2026-07-01", to: "2026-07-03", fromOp: null, toOp: "$lt" }, "YYYY-MM-DD"),
|
|
158
|
+
// [
|
|
159
|
+
// "2026-07-01",
|
|
160
|
+
// "2026-07-02",
|
|
161
|
+
// ]
|
|
162
|
+
// );
|
|
163
|
+
// });
|
|
167
164
|
test("excludes both bounds", () => {
|
|
168
|
-
assert.deepEqual(fillDates({
|
|
169
|
-
from: "2026-07-01",
|
|
170
|
-
to: "2026-07-05",
|
|
171
|
-
fromOp: "$gt",
|
|
172
|
-
toOp: "$lt",
|
|
173
|
-
}, "YYYY-MM-DD"), [
|
|
165
|
+
assert.deepEqual(fillDates({ from: "2026-07-01", to: "2026-07-05", fromOp: "$gt", toOp: "$lt" }, "YYYY-MM-DD"), [
|
|
174
166
|
"2026-07-02",
|
|
175
167
|
"2026-07-03",
|
|
176
168
|
"2026-07-04",
|
|
177
169
|
]);
|
|
178
170
|
});
|
|
179
171
|
test("returns empty when exclusive bounds collapse range", () => {
|
|
180
|
-
assert.deepEqual(fillDates({
|
|
181
|
-
from: "2026-07-01",
|
|
182
|
-
to: "2026-07-02",
|
|
183
|
-
fromOp: "$gt",
|
|
184
|
-
toOp: "$lt",
|
|
185
|
-
}, "YYYY-MM-DD"), []);
|
|
172
|
+
assert.deepEqual(fillDates({ from: "2026-07-01", to: "2026-07-02", fromOp: "$gt", toOp: "$lt" }, "YYYY-MM-DD"), []);
|
|
186
173
|
});
|
|
187
174
|
});
|
|
@@ -1,75 +1,56 @@
|
|
|
1
1
|
import { describe, test } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { matchPolicy, overlaps, contains, intersects, applySuffixPolicy } from "../policy.js";
|
|
4
|
+
const defaultBounds = { values: [], from: -Infinity, to: Infinity, fromOp: "$gte", toOp: "$lte" };
|
|
4
5
|
/* ============================================================
|
|
5
6
|
* overlaps()
|
|
6
7
|
* ============================================================ */
|
|
7
8
|
describe("overlaps()", () => {
|
|
8
9
|
test("overlaps: identical ranges", () => {
|
|
9
|
-
assert.equal(overlaps({ from: 10, to: 20 }, { from: 10, to: 20 }), true);
|
|
10
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, to: 20 }, { ...defaultBounds, from: 10, to: 20 }), true);
|
|
10
11
|
});
|
|
11
12
|
test("overlaps: partial overlap", () => {
|
|
12
|
-
assert.equal(overlaps({ from: 10, to: 20 }, { from: 15, to: 25 }), true);
|
|
13
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, to: 20 }, { ...defaultBounds, from: 15, to: 25 }), true);
|
|
13
14
|
});
|
|
14
15
|
test("overlaps: no overlap", () => {
|
|
15
|
-
assert.equal(overlaps({ from: 10, to: 20 }, { from: 21, to: 30 }), false);
|
|
16
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, to: 20 }, { ...defaultBounds, from: 21, to: 30 }), false);
|
|
16
17
|
});
|
|
17
18
|
test("overlaps: open ended lower", () => {
|
|
18
|
-
assert.equal(overlaps({ to: 10 }, { from: 5 }), true);
|
|
19
|
+
assert.equal(overlaps({ ...defaultBounds, to: 10 }, { ...defaultBounds, from: 5 }), true);
|
|
19
20
|
});
|
|
20
21
|
test("overlaps: open ended upper", () => {
|
|
21
|
-
assert.equal(overlaps({ from: 20 }, { to: 10 }), false);
|
|
22
|
+
assert.equal(overlaps({ ...defaultBounds, from: 20 }, { ...defaultBounds, to: 10 }), false);
|
|
22
23
|
});
|
|
23
24
|
describe("overlaps() boundary semantics", () => {
|
|
24
25
|
test("touching: open/open does not overlap", () => {
|
|
25
|
-
assert.equal(overlaps({ to: 10, toOp: "$lt" }, { from: 10, fromOp: "$gt" }), false);
|
|
26
|
+
assert.equal(overlaps({ ...defaultBounds, to: 10, toOp: "$lt" }, { ...defaultBounds, from: 10, fromOp: "$gt" }), false);
|
|
26
27
|
});
|
|
27
28
|
test("touching: closed/closed overlaps", () => {
|
|
28
|
-
assert.equal(overlaps({ to: 10, toOp: "$lte" }, { from: 10, fromOp: "$gte" }), true);
|
|
29
|
+
assert.equal(overlaps({ ...defaultBounds, to: 10, toOp: "$lte" }, { ...defaultBounds, from: 10, fromOp: "$gte" }), true);
|
|
29
30
|
});
|
|
30
31
|
test("touching: closed/open does not overlap", () => {
|
|
31
|
-
assert.equal(overlaps({ to: 10, toOp: "$lte" }, { from: 10, fromOp: "$gt" }), false);
|
|
32
|
+
assert.equal(overlaps({ ...defaultBounds, to: 10, toOp: "$lte" }, { ...defaultBounds, from: 10, fromOp: "$gt" }), false);
|
|
32
33
|
});
|
|
33
34
|
test("touching: open/closed does not overlap", () => {
|
|
34
|
-
assert.equal(overlaps({ to: 10, toOp: "$lt" }, { from: 10, fromOp: "$gte" }), false);
|
|
35
|
+
assert.equal(overlaps({ ...defaultBounds, to: 10, toOp: "$lt" }, { ...defaultBounds, from: 10, fromOp: "$gte" }), false);
|
|
35
36
|
});
|
|
36
37
|
test("touching: reverse order closed/closed overlaps", () => {
|
|
37
|
-
assert.equal(overlaps({ from: 10, fromOp: "$gte" }, { to: 10, toOp: "$lte" }), true);
|
|
38
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, fromOp: "$gte" }, { ...defaultBounds, to: 10, toOp: "$lte" }), true);
|
|
38
39
|
});
|
|
39
40
|
test("touching: reverse order open/open does not overlap", () => {
|
|
40
|
-
assert.equal(overlaps({ from: 10, fromOp: "$gt" }, { to: 10, toOp: "$lt" }), false);
|
|
41
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, fromOp: "$gt" }, { ...defaultBounds, to: 10, toOp: "$lt" }), false);
|
|
41
42
|
});
|
|
42
43
|
test("identical single-point closed intervals overlap", () => {
|
|
43
|
-
assert.equal(overlaps({
|
|
44
|
-
from: 10,
|
|
45
|
-
to: 10,
|
|
46
|
-
fromOp: "$gte",
|
|
47
|
-
toOp: "$lte"
|
|
48
|
-
}, {
|
|
49
|
-
from: 10,
|
|
50
|
-
to: 10,
|
|
51
|
-
fromOp: "$gte",
|
|
52
|
-
toOp: "$lte"
|
|
53
|
-
}), true);
|
|
44
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, to: 10, fromOp: "$gte", toOp: "$lte" }, { ...defaultBounds, from: 10, to: 10, fromOp: "$gte", toOp: "$lte" }), true);
|
|
54
45
|
});
|
|
55
46
|
test("identical single-point open intervals do not overlap", () => {
|
|
56
|
-
assert.equal(overlaps({
|
|
57
|
-
from: 10,
|
|
58
|
-
to: 10,
|
|
59
|
-
fromOp: "$gt",
|
|
60
|
-
toOp: "$lt"
|
|
61
|
-
}, {
|
|
62
|
-
from: 10,
|
|
63
|
-
to: 10,
|
|
64
|
-
fromOp: "$gt",
|
|
65
|
-
toOp: "$lt"
|
|
66
|
-
}), false);
|
|
47
|
+
assert.equal(overlaps({ ...defaultBounds, from: 10, to: 10, fromOp: "$gt", toOp: "$lt" }, { ...defaultBounds, from: 10, to: 10, fromOp: "$gt", toOp: "$lt" }), false);
|
|
67
48
|
});
|
|
68
49
|
test("infinite lower bound with touching closed endpoint overlaps", () => {
|
|
69
|
-
assert.equal(overlaps({ to: 5, toOp: "$lte" }, { from: 5, fromOp: "$gte" }), true);
|
|
50
|
+
assert.equal(overlaps({ ...defaultBounds, to: 5, toOp: "$lte" }, { ...defaultBounds, from: 5, fromOp: "$gte" }), true);
|
|
70
51
|
});
|
|
71
52
|
test("infinite lower bound with touching open endpoint does not overlap", () => {
|
|
72
|
-
assert.equal(overlaps({ to: 5, toOp: "$lt" }, { from: 5, fromOp: "$gt" }), false);
|
|
53
|
+
assert.equal(overlaps({ ...defaultBounds, to: 5, toOp: "$lt" }, { ...defaultBounds, from: 5, fromOp: "$gt" }), false);
|
|
73
54
|
});
|
|
74
55
|
});
|
|
75
56
|
});
|
|
@@ -78,89 +59,69 @@ describe("overlaps()", () => {
|
|
|
78
59
|
* ============================================================ */
|
|
79
60
|
describe("contains()", () => {
|
|
80
61
|
test("contains: inside", () => {
|
|
81
|
-
assert.equal(contains({ from: 10, to: 20 }, 15), true);
|
|
62
|
+
assert.equal(contains({ ...defaultBounds, from: 10, to: 20 }, 15), true);
|
|
82
63
|
});
|
|
83
64
|
test("contains: below", () => {
|
|
84
|
-
assert.equal(contains({ from: 10, to: 20 }, 5), false);
|
|
65
|
+
assert.equal(contains({ ...defaultBounds, from: 10, to: 20 }, 5), false);
|
|
85
66
|
});
|
|
86
67
|
test("contains: above", () => {
|
|
87
|
-
assert.equal(contains({ from: 10, to: 20 }, 25), false);
|
|
68
|
+
assert.equal(contains({ ...defaultBounds, from: 10, to: 20 }, 25), false);
|
|
88
69
|
});
|
|
89
70
|
test("contains: lower bound", () => {
|
|
90
|
-
assert.equal(contains({ from: 10, to: 20 }, 10), true);
|
|
71
|
+
assert.equal(contains({ ...defaultBounds, from: 10, to: 20 }, 10), true);
|
|
91
72
|
});
|
|
92
73
|
test("contains: upper bound", () => {
|
|
93
|
-
assert.equal(contains({ from: 10, to: 20 }, 20), true);
|
|
74
|
+
assert.equal(contains({ ...defaultBounds, from: 10, to: 20 }, 20), true);
|
|
94
75
|
});
|
|
95
76
|
test("contains: gt excludes lower bound", () => {
|
|
96
|
-
assert.equal(contains({ from: 5, fromOp: "$gt" }, 5), false);
|
|
77
|
+
assert.equal(contains({ ...defaultBounds, from: 5, fromOp: "$gt" }, 5), false);
|
|
97
78
|
});
|
|
98
79
|
test("contains: gte includes lower bound", () => {
|
|
99
|
-
assert.equal(contains({ from: 5, fromOp: "$gte" }, 5), true);
|
|
80
|
+
assert.equal(contains({ ...defaultBounds, from: 5, fromOp: "$gte" }, 5), true);
|
|
100
81
|
});
|
|
101
82
|
test("contains: lt excludes upper bound", () => {
|
|
102
|
-
assert.equal(contains({ to: 10, toOp: "$lt" }, 10), false);
|
|
83
|
+
assert.equal(contains({ ...defaultBounds, to: 10, toOp: "$lt" }, 10), false);
|
|
103
84
|
});
|
|
104
85
|
test("contains: lte includes upper bound", () => {
|
|
105
|
-
assert.equal(contains({ to: 10, toOp: "$lte" }, 10), true);
|
|
86
|
+
assert.equal(contains({ ...defaultBounds, to: 10, toOp: "$lte" }, 10), true);
|
|
106
87
|
});
|
|
107
88
|
test("contains: gt/lt excludes both endpoints", () => {
|
|
108
|
-
const bounds = {
|
|
109
|
-
from: 5,
|
|
110
|
-
fromOp: "$gt",
|
|
111
|
-
to: 10,
|
|
112
|
-
toOp: "$lt"
|
|
113
|
-
};
|
|
89
|
+
const bounds = { ...defaultBounds, from: 5, fromOp: "$gt", to: 10, toOp: "$lt" };
|
|
114
90
|
assert.equal(contains(bounds, 5), false);
|
|
115
91
|
assert.equal(contains(bounds, 10), false);
|
|
116
92
|
assert.equal(contains(bounds, 7), true);
|
|
117
93
|
});
|
|
118
94
|
test("contains: gte/lte includes both endpoints", () => {
|
|
119
|
-
const bounds = {
|
|
120
|
-
from: 5,
|
|
121
|
-
fromOp: "$gte",
|
|
122
|
-
to: 10,
|
|
123
|
-
toOp: "$lte"
|
|
124
|
-
};
|
|
95
|
+
const bounds = { ...defaultBounds, from: 5, fromOp: "$gte", to: 10, toOp: "$lte" };
|
|
125
96
|
assert.equal(contains(bounds, 5), true);
|
|
126
97
|
assert.equal(contains(bounds, 10), true);
|
|
127
98
|
assert.equal(contains(bounds, 7), true);
|
|
128
99
|
});
|
|
129
100
|
test("contains: gt/lte mixed", () => {
|
|
130
|
-
const bounds = {
|
|
131
|
-
from: 5,
|
|
132
|
-
fromOp: "$gt",
|
|
133
|
-
to: 10,
|
|
134
|
-
toOp: "$lte"
|
|
135
|
-
};
|
|
101
|
+
const bounds = { ...defaultBounds, from: 5, fromOp: "$gt", to: 10, toOp: "$lte" };
|
|
136
102
|
assert.equal(contains(bounds, 5), false);
|
|
137
103
|
assert.equal(contains(bounds, 10), true);
|
|
138
104
|
});
|
|
139
105
|
test("contains: gte/lt mixed", () => {
|
|
140
|
-
const bounds = {
|
|
141
|
-
from: 5,
|
|
142
|
-
fromOp: "$gte",
|
|
143
|
-
to: 10,
|
|
144
|
-
toOp: "$lt"
|
|
145
|
-
};
|
|
106
|
+
const bounds = { ...defaultBounds, from: 5, fromOp: "$gte", to: 10, toOp: "$lt" };
|
|
146
107
|
assert.equal(contains(bounds, 5), true);
|
|
147
108
|
assert.equal(contains(bounds, 10), false);
|
|
148
109
|
});
|
|
149
110
|
test("contains: value below lower bound", () => {
|
|
150
|
-
assert.equal(contains({ from: 5, fromOp: "$gte" }, 4), false);
|
|
111
|
+
assert.equal(contains({ ...defaultBounds, from: 5, fromOp: "$gte" }, 4), false);
|
|
151
112
|
});
|
|
152
113
|
test("contains: value above upper bound", () => {
|
|
153
|
-
assert.equal(contains({ to: 10, toOp: "$lte" }, 11), false);
|
|
114
|
+
assert.equal(contains({ ...defaultBounds, to: 10, toOp: "$lte" }, 11), false);
|
|
154
115
|
});
|
|
155
116
|
test("contains: open lower bound", () => {
|
|
156
|
-
assert.equal(contains({ to: 10, toOp: "$lte" }, -1000), true);
|
|
117
|
+
assert.equal(contains({ ...defaultBounds, to: 10, toOp: "$lte" }, -1000), true);
|
|
157
118
|
});
|
|
158
119
|
test("contains: open upper bound", () => {
|
|
159
|
-
assert.equal(contains({ from: 5, fromOp: "$gte" }, 1000), true);
|
|
120
|
+
assert.equal(contains({ ...defaultBounds, from: 5, fromOp: "$gte" }, 1000), true);
|
|
160
121
|
});
|
|
161
122
|
test("contains: completely unbounded", () => {
|
|
162
|
-
assert.equal(contains({}, -100), true);
|
|
163
|
-
assert.equal(contains({}, 100), true);
|
|
123
|
+
assert.equal(contains({ ...defaultBounds, }, -100), true);
|
|
124
|
+
assert.equal(contains({ ...defaultBounds, }, 100), true);
|
|
164
125
|
});
|
|
165
126
|
});
|
|
166
127
|
/* ============================================================
|
|
@@ -174,22 +135,22 @@ describe("intersects()", () => {
|
|
|
174
135
|
assert.equal(intersects(["A"], null, ["B"], null), false);
|
|
175
136
|
});
|
|
176
137
|
test("intersects: value ↔ range", () => {
|
|
177
|
-
assert.equal(intersects([10], null, [], { from: 5 }), true);
|
|
138
|
+
assert.equal(intersects([10], null, [], { ...defaultBounds, from: 5 }), true);
|
|
178
139
|
});
|
|
179
140
|
test("intersects: value ↔ range miss", () => {
|
|
180
|
-
assert.equal(intersects([2], null, [], { from: 5 }), false);
|
|
141
|
+
assert.equal(intersects([2], null, [], { ...defaultBounds, from: 5 }), false);
|
|
181
142
|
});
|
|
182
143
|
test("intersects: range ↔ value", () => {
|
|
183
|
-
assert.equal(intersects([], { from: 5 }, [10], null), true);
|
|
144
|
+
assert.equal(intersects([], { ...defaultBounds, from: 5 }, [10], null), true);
|
|
184
145
|
});
|
|
185
146
|
test("intersects: range ↔ value miss", () => {
|
|
186
|
-
assert.equal(intersects([], { from: 5 }, [2], null), false);
|
|
147
|
+
assert.equal(intersects([], { ...defaultBounds, from: 5 }, [2], null), false);
|
|
187
148
|
});
|
|
188
149
|
test("intersects: range ↔ range", () => {
|
|
189
|
-
assert.equal(intersects([], { from: 10 }, [], { from: 20 }), true);
|
|
150
|
+
assert.equal(intersects([], { ...defaultBounds, from: 10 }, [], { ...defaultBounds, from: 20 }), true);
|
|
190
151
|
});
|
|
191
152
|
test("intersects: range ↔ range miss", () => {
|
|
192
|
-
assert.equal(intersects([], { to: 5 }, [], { from: 10 }), false);
|
|
153
|
+
assert.equal(intersects([], { ...defaultBounds, to: 5 }, [], { ...defaultBounds, from: 10 }), false);
|
|
193
154
|
});
|
|
194
155
|
});
|
|
195
156
|
/* ============================================================
|
package/dist/libs/dip.js
CHANGED
|
@@ -15,6 +15,7 @@ export const companyMeta = Elabase.companyMeta;
|
|
|
15
15
|
export const outletMeta = Elabase.outletMeta;
|
|
16
16
|
export const customMeta = Elabase.customMeta;
|
|
17
17
|
export const schema = Elabase.schema;
|
|
18
|
+
export const DipMeta = Elabase.DipMeta;
|
|
18
19
|
export const isDipMeta = Elabase.isDipMeta;
|
|
19
20
|
export const excludeCollectionConfig = Elabase.excludeCollectionConfig;
|
|
20
21
|
export const includeCollectionConfig = Elabase.includeCollectionConfig;
|
|
@@ -28,34 +29,36 @@ export async function insertSync(meta, feature, date, uid, ref, type) {
|
|
|
28
29
|
await Elabase.insert(meta, collection, data);
|
|
29
30
|
}
|
|
30
31
|
export const IdempotentDip = () => {
|
|
31
|
-
|
|
32
|
+
const state = {
|
|
32
33
|
txn: '',
|
|
33
34
|
meta: undefined,
|
|
34
|
-
new: (async function (meta, txn, blank) {
|
|
35
|
-
this.txn = txn;
|
|
36
|
-
this.meta = meta;
|
|
37
|
-
return blank ? this : ((await Elabase.query(this.meta, "txns", { _id: this.txn })).length ? false : this);
|
|
38
|
-
}),
|
|
39
|
-
insert: (async function (collection, query, data) {
|
|
40
|
-
await Elabase.update(this.meta, collection, query, { $setOnInsert: data }, { upsert: true });
|
|
41
|
-
}),
|
|
42
|
-
update: (async function (collection, query, data, rollback) {
|
|
43
|
-
let token = { [this.txn]: true };
|
|
44
|
-
let idempotent = { [this.txn]: { $exists: rollback ?? false } };
|
|
45
|
-
let result = await Elabase.update(this.meta, collection, { ...query, ...idempotent }, { ...data, $setOnInsert: undefined, $set: { ...(data.$set ?? {}), ...token } });
|
|
46
|
-
return result.count ? true : (await Elabase.query(this.meta, collection, { ...query, ...idempotent })).length;
|
|
47
|
-
}),
|
|
48
|
-
upsert: (async function (collection, query, data, rollback) {
|
|
49
|
-
await this.insert(collection, query, data.$setOnInsert);
|
|
50
|
-
return await this.update(collection, query, data, rollback);
|
|
51
|
-
}),
|
|
52
|
-
cleanup: (async function (collection, query) {
|
|
53
|
-
await Elabase.update(this.meta, collection, query, { $unset: { [this.txn]: true } });
|
|
54
|
-
}),
|
|
55
|
-
finish: (async function () {
|
|
56
|
-
return await Elabase.update(this.meta, "txns", { _id: this.txn }, {}, { upsert: true });
|
|
57
|
-
})
|
|
58
35
|
};
|
|
36
|
+
const idip = {};
|
|
37
|
+
idip.new = async function (meta, txn, blank) {
|
|
38
|
+
state.txn = txn;
|
|
39
|
+
state.meta = meta;
|
|
40
|
+
return blank ? idip : ((await Elabase.query(state.meta, "txns", { _id: state.txn })).length ? false : idip);
|
|
41
|
+
};
|
|
42
|
+
idip.insert = async function (collection, query, data) {
|
|
43
|
+
await Elabase.update(state.meta, collection, query, { $setOnInsert: data }, { upsert: true });
|
|
44
|
+
};
|
|
45
|
+
idip.update = async function (collection, query, data, rollback) {
|
|
46
|
+
let token = { [state.txn]: true };
|
|
47
|
+
let idempotent = { [state.txn]: { $exists: rollback ?? false } };
|
|
48
|
+
let result = await Elabase.update(state.meta, collection, { ...query, ...idempotent }, { ...data, $setOnInsert: undefined, $set: { ...(data.$set ?? {}), ...token } });
|
|
49
|
+
return result.count ? true : (await Elabase.query(state.meta, collection, { ...query, ...idempotent })).length;
|
|
50
|
+
};
|
|
51
|
+
idip.upsert = async function (collection, query, data, rollback) {
|
|
52
|
+
await idip.insert(collection, query, data.$setOnInsert);
|
|
53
|
+
return await idip.update(collection, query, data, rollback);
|
|
54
|
+
};
|
|
55
|
+
idip.cleanup = async function (collection, query) {
|
|
56
|
+
await Elabase.update(state.meta, collection, query, { $unset: { [state.txn]: true } });
|
|
57
|
+
};
|
|
58
|
+
idip.finish = async function () {
|
|
59
|
+
return await Elabase.update(state.meta, "txns", { _id: state.txn }, {}, { upsert: true });
|
|
60
|
+
};
|
|
61
|
+
return idip;
|
|
59
62
|
};
|
|
60
63
|
export const idip = async (message, callback, cleanup) => {
|
|
61
64
|
if (!callback)
|
|
@@ -93,7 +96,7 @@ export const insertKeys = (message, meta) => {
|
|
|
93
96
|
...(meta?.outlet ? { "outlet": meta.outlet } : {}),
|
|
94
97
|
};
|
|
95
98
|
};
|
|
96
|
-
export const updateKeys = message => {
|
|
99
|
+
export const updateKeys = (message) => {
|
|
97
100
|
return {
|
|
98
101
|
"updated": message.date,
|
|
99
102
|
"updatedBy": message.meta.staff,
|
package/dist/libs/dipper.js
CHANGED