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
package/libs/dip/suffix/index.ts
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
|
|
2
|
+
export type BoundValue = number | string | Date
|
|
3
|
+
export type BoundFromOp = "$gt" | "$gte"
|
|
4
|
+
export type BoundToOp = "$lt" | "$lte"
|
|
2
5
|
|
|
6
|
+
export type Bounds = {
|
|
7
|
+
values: unknown[],
|
|
8
|
+
from: BoundValue | unknown;
|
|
9
|
+
to: BoundValue | unknown;
|
|
10
|
+
fromOp: BoundFromOp | unknown;
|
|
11
|
+
toOp: BoundToOp | unknown;
|
|
12
|
+
}
|
|
13
|
+
export type AbsoluteBounds = {
|
|
14
|
+
from: BoundValue;
|
|
15
|
+
to: BoundValue;
|
|
16
|
+
fromOp: BoundFromOp;
|
|
17
|
+
toOp: BoundToOp;
|
|
18
|
+
}
|
|
3
19
|
|
|
4
|
-
|
|
5
|
-
|
|
20
|
+
|
|
21
|
+
function flatten_id_values(target_key: string, values: unknown): unknown[] {
|
|
22
|
+
let flattened: unknown[] = [];
|
|
6
23
|
flatten_value(target_key, values, flattened, false);
|
|
7
24
|
return flattened
|
|
8
25
|
}
|
|
9
26
|
|
|
10
|
-
function flatten_value(target_key, value, flattened, ancestor_has_id) {
|
|
27
|
+
function flatten_value(target_key: string, value: unknown, flattened: unknown[], ancestor_has_id: boolean) {
|
|
11
28
|
const is_array = Array.isArray(value)
|
|
12
29
|
const is_object = value !== null && !is_array && typeof value === "object";
|
|
13
30
|
const is_regular = typeof value === "boolean" || typeof value === "number" || typeof value === "string"
|
|
14
|
-
const map = value
|
|
15
|
-
const arr = value
|
|
31
|
+
const map = value as Record<string, unknown>
|
|
32
|
+
const arr = value as unknown[]
|
|
16
33
|
|
|
17
34
|
if (is_regular) {
|
|
18
35
|
flattened.push(value);
|
|
@@ -72,7 +89,7 @@ function flatten_value(target_key, value, flattened, ancestor_has_id) {
|
|
|
72
89
|
}
|
|
73
90
|
|
|
74
91
|
|
|
75
|
-
export function entries(target_key: string, query, binary_slice?: Buffer) {
|
|
92
|
+
export function entries(target_key: string, query: unknown, binary_slice?: Buffer): unknown[] {
|
|
76
93
|
let result = flatten_id_values(target_key, query); // extract all valid _id
|
|
77
94
|
|
|
78
95
|
// let cows = result.map(v => extract_direct_id(v, binary_slice))
|
|
@@ -95,19 +112,21 @@ export function entries(target_key: string, query, binary_slice?: Buffer) {
|
|
|
95
112
|
// reduceRanges() intentionally computes a conservative (wider) approximation.
|
|
96
113
|
// It is used only for suffix policy planning, where false positives are acceptable
|
|
97
114
|
// (extra suffix scans) but false negatives are not.
|
|
98
|
-
export function reduceRanges(values) {
|
|
115
|
+
export function reduceRanges(values: unknown[]) {
|
|
99
116
|
let gt = null;
|
|
100
117
|
let gte = null;
|
|
101
118
|
let lt = null;
|
|
102
119
|
let lte = null;
|
|
103
120
|
const other = [];
|
|
104
121
|
|
|
105
|
-
for (const
|
|
106
|
-
if (typeof
|
|
107
|
-
other.push(
|
|
122
|
+
for (const v of values) {
|
|
123
|
+
if (typeof v !== "object" || v === null || Array.isArray(v)) {
|
|
124
|
+
other.push(v);
|
|
108
125
|
continue;
|
|
109
126
|
}
|
|
110
127
|
|
|
128
|
+
const value = v as Record<string, {$gt?: BoundValue, $gte?: BoundValue, $lt?: BoundValue, $lte?: BoundValue}>
|
|
129
|
+
|
|
111
130
|
if ("$gt" in value) {
|
|
112
131
|
if (gt === null || value.$gt < gt)
|
|
113
132
|
gt = value.$gt;
|
|
@@ -160,31 +179,27 @@ export function reduceRanges(values) {
|
|
|
160
179
|
return other;
|
|
161
180
|
}
|
|
162
181
|
|
|
163
|
-
|
|
164
|
-
values: any[],
|
|
165
|
-
from: number | string | Date;
|
|
166
|
-
to: number | string | Date;
|
|
167
|
-
fromOp: "$gt" | "$gte";
|
|
168
|
-
toOp: "$lt" | "$lte";
|
|
169
|
-
}
|
|
182
|
+
|
|
170
183
|
|
|
171
184
|
// reduceRanges() resolves conflicting bounds before extractBounds() runs.
|
|
172
185
|
// extractBounds() receives at most one lower bound and atmost one upper bound. reduceRanges() ensures this
|
|
173
186
|
// The for loop in extractBounds() may look slightly misleading because it looks like it is designed to resolve conflicts: but reduceRanges() has already done the conflict resolution.
|
|
174
187
|
// NOTE CRITICAL: extractBounds() MUST ONLY BE RUN ON THE OUTPUT OF reduceRanges()
|
|
175
|
-
export function extractBounds(values): Bounds {
|
|
176
|
-
let lower = null;
|
|
177
|
-
let upper = null;
|
|
178
|
-
let lowerOp = null
|
|
179
|
-
let upperOp = null
|
|
188
|
+
export function extractBounds(values: unknown[]): Bounds {
|
|
189
|
+
let lower: BoundValue | unknown = null;
|
|
190
|
+
let upper: BoundValue | unknown = null;
|
|
191
|
+
let lowerOp: BoundFromOp | unknown = null
|
|
192
|
+
let upperOp: BoundToOp | unknown = null
|
|
180
193
|
const remaining = [];
|
|
181
194
|
|
|
182
|
-
for (const
|
|
183
|
-
if (typeof
|
|
184
|
-
remaining.push(
|
|
195
|
+
for (const v of values) {
|
|
196
|
+
if (typeof v !== "object" || v === null || Array.isArray(v)) {
|
|
197
|
+
remaining.push(v);
|
|
185
198
|
continue;
|
|
186
199
|
}
|
|
187
200
|
|
|
201
|
+
const value = v as Record<string, {$gt?: BoundValue, $gte?: BoundValue, $lt?: BoundValue, $lte?: BoundValue}>
|
|
202
|
+
|
|
188
203
|
if ("$gt" in value) {
|
|
189
204
|
lower = value.$gt;
|
|
190
205
|
lowerOp = "$gt"
|
|
@@ -212,7 +227,7 @@ export function extractBounds(values): Bounds {
|
|
|
212
227
|
}
|
|
213
228
|
|
|
214
229
|
// Converts exclusive bounds ($gt/$lt) into inclusive bounds
|
|
215
|
-
export function getNormalizedBounds(bounds_t:
|
|
230
|
+
export function getNormalizedBounds<T extends Bounds | AbsoluteBounds>(bounds_t: T, type: "number" | "date"): T {
|
|
216
231
|
let bounds = {...bounds_t}
|
|
217
232
|
|
|
218
233
|
if (type === "number") {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {entries, reduceRanges, extractBounds} from './index.ts'
|
|
1
|
+
import {entries, reduceRanges, extractBounds, type Bounds, type BoundValue} from './index.ts'
|
|
2
2
|
import {suffix} from './suffix.ts'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
export function overlaps(a, b) {
|
|
7
|
+
export function overlaps(a: Bounds, b: Bounds) {
|
|
8
|
+
|
|
8
9
|
const aFrom = a.from ?? -Infinity;
|
|
9
10
|
const aTo = a.to ?? Infinity;
|
|
10
11
|
|
|
@@ -12,9 +13,11 @@ export function overlaps(a, b) {
|
|
|
12
13
|
const bTo = b.to ?? Infinity;
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
const max = (a: BoundValue, b: BoundValue) => a > b ? a : b
|
|
17
|
+
const min = (a: BoundValue, b: BoundValue) => a < b ? a : b
|
|
15
18
|
|
|
16
|
-
const left =
|
|
17
|
-
const right =
|
|
19
|
+
const left = max(aFrom as BoundValue, bFrom as BoundValue);
|
|
20
|
+
const right = min(aTo as BoundValue, bTo as BoundValue);
|
|
18
21
|
|
|
19
22
|
if (left < right)
|
|
20
23
|
return true;
|
|
@@ -35,7 +38,7 @@ export function overlaps(a, b) {
|
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
|
|
38
|
-
export function contains(bounds, value) {
|
|
41
|
+
export function contains(bounds: Bounds, value: BoundValue) {
|
|
39
42
|
const from = bounds.from ?? -Infinity;
|
|
40
43
|
const to = bounds.to ?? Infinity;
|
|
41
44
|
|
|
@@ -56,7 +59,7 @@ export function contains(bounds, value) {
|
|
|
56
59
|
// return value >= from && value <= to;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
export function intersects(w_values, w_bounds, q_values, q_bounds) {
|
|
62
|
+
export function intersects(w_values: BoundValue[], w_bounds: Bounds | null, q_values: BoundValue[], q_bounds: Bounds | null) {
|
|
60
63
|
// value ↔ value
|
|
61
64
|
for (const value of w_values) {
|
|
62
65
|
if (q_values.includes(value))
|
|
@@ -88,7 +91,7 @@ export function intersects(w_values, w_bounds, q_values, q_bounds) {
|
|
|
88
91
|
|
|
89
92
|
|
|
90
93
|
// NOTE: Matching is based on intersection, not equality. A policy matches if, for every key in `when`, there exists at least one value that satisfies both the `when` constraint and the query constraint.
|
|
91
|
-
export function matchPolicy(query, when, g_obj?: Record<string,
|
|
94
|
+
export function matchPolicy(query: Record<string, any>, when: Record<string, any>, g_obj?: Record<string, unknown[]>) {
|
|
92
95
|
let obj = g_obj ?? {}
|
|
93
96
|
for (let key in when) {
|
|
94
97
|
if (key === "$and" || key === "$or") {
|
|
@@ -124,7 +127,7 @@ export function matchPolicy(query, when, g_obj?: Record<string, any>) {
|
|
|
124
127
|
q_values = q_values.filter(item => typeof item !== "object")
|
|
125
128
|
const q_bounds = q_ranges.length ? extractBounds(reduceRanges(q_ranges)) : null
|
|
126
129
|
|
|
127
|
-
if (!intersects(w_values, w_bounds, q_values, q_bounds))
|
|
130
|
+
if (!intersects(w_values as BoundValue[], w_bounds, q_values as BoundValue[], q_bounds))
|
|
128
131
|
return false;
|
|
129
132
|
|
|
130
133
|
}
|
|
@@ -132,14 +135,14 @@ export function matchPolicy(query, when, g_obj?: Record<string, any>) {
|
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
|
|
138
|
+
type SuffixItem = { key?: string; value?: string; type: string; ls_threshold?: number; min?: number; max?: number }
|
|
135
139
|
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
type CollectionsJsonType = Record<string, {policy?: {when: object, suffix: SuffixItem[]}[]}>
|
|
138
141
|
type Arg = { db: string; collection: string[]; }
|
|
139
142
|
|
|
140
|
-
export async function applySuffixPolicy(COLLECTIONS_JSON,
|
|
141
|
-
collections = Array.isArray(
|
|
142
|
-
let suffixes = []
|
|
143
|
+
export async function applySuffixPolicy(COLLECTIONS_JSON: CollectionsJsonType, cols: string | string[], query: Record<string, any>, insertMode?: boolean, arg?: Arg) {
|
|
144
|
+
const collections = Array.isArray(cols) ? cols : [cols]
|
|
145
|
+
let suffixes: string[] = []
|
|
143
146
|
|
|
144
147
|
for (let collection of collections) {
|
|
145
148
|
const collection_policy = COLLECTIONS_JSON[collection]?.policy ?? []
|