corebasic 1.0.229 → 1.0.231

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/libs/cpp.ts CHANGED
@@ -1,8 +1,10 @@
1
1
 
2
2
  import crypto from 'node:crypto';
3
3
 
4
+ type ValueRef = { value: bigint }
5
+ type BytesRef = { value: number }
4
6
 
5
- function readContent(buffer: Uint8Array, valueRef, bytesRef) { // Buffer is assignable to Uint8Array so no need for Buffer | Uint8Array
7
+ function readContent(buffer: Uint8Array, valueRef: ValueRef, bytesRef: BytesRef) { // Buffer is assignable to Uint8Array so no need for Buffer | Uint8Array
6
8
  const MASK = 0x7F;
7
9
  const MSB = 0x80;
8
10
  const MAX_VLQ_BYTES = 10;
@@ -21,7 +23,7 @@ function readContent(buffer: Uint8Array, valueRef, bytesRef) { // Buffer is assi
21
23
  return false;
22
24
  }
23
25
 
24
- const byte = view[lenBytes];
26
+ const byte = view[lenBytes]!;
25
27
  lenBytes++;
26
28
 
27
29
  length |= BigInt(byte & MASK) << shift;
@@ -41,7 +43,7 @@ function readContent(buffer: Uint8Array, valueRef, bytesRef) { // Buffer is assi
41
43
 
42
44
 
43
45
 
44
- export function vlqToUint64(arrayBuffer) {
46
+ export function vlqToUint64(arrayBuffer: Uint8Array) {
45
47
  // Objects act as containers to simulate C++ pointers/references
46
48
  const valueRef = { value: 0n };
47
49
  const bytesRef = { value: 0 };
@@ -63,7 +65,7 @@ export function vlqToUint64(arrayBuffer) {
63
65
 
64
66
 
65
67
 
66
- function writeVlqcontent(buffer, value) {
68
+ function writeVlqcontent(buffer: Buffer, value: number | bigint) {
67
69
  const MASK = 0x7Fn;
68
70
  const MSB = 0x80;
69
71
  let bufferPtr = 0;
@@ -81,7 +83,7 @@ function writeVlqcontent(buffer, value) {
81
83
  return bufferPtr;
82
84
  }
83
85
 
84
- export function uint64ToVlq(value) {
86
+ export function uint64ToVlq(value: number | bigint) {
85
87
  // 10 bytes is the maximum VLQ size for a uint64
86
88
  const out = Buffer.allocUnsafe(10);
87
89
  const size = writeVlqcontent(out, value);
@@ -93,7 +95,7 @@ export function uint64ToVlq(value) {
93
95
 
94
96
 
95
97
 
96
- export function sliceArrayBuffer(buffer, offset, length) {
98
+ export function sliceArrayBuffer(buffer: Buffer | Uint8Array, offset: number, length: number) {
97
99
  // Ensure we are working with a Node.js Buffer
98
100
  const buf = Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer);
99
101
  const totalSize = buf.length;
@@ -113,13 +115,13 @@ export function sliceArrayBuffer(buffer, offset, length) {
113
115
  return buf.subarray(offset, offset + length); // COW/Shallow copy I hope or else what is the use of this function
114
116
  }
115
117
 
116
- export function stringToUtf8ArrayBuffer(arg) {
118
+ export function stringToUtf8ArrayBuffer(arg: string) {
117
119
  // Converts the string into a Node.js Buffer encoded in UTF-8
118
120
  return Buffer.from(arg, 'utf8');
119
121
  }
120
122
 
121
123
 
122
- export function numberToSortableBytes(value) {
124
+ export function numberToSortableBytes(value: number) {
123
125
  // 1. Create an 8-byte buffer and a data view to read/write raw bits
124
126
  const buffer = Buffer.alloc(8);
125
127
  const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
@@ -148,7 +150,7 @@ export function numberToSortableBytes(value) {
148
150
 
149
151
 
150
152
 
151
- export function defaultHash(buffer) {
153
+ export function defaultHash(buffer: Buffer | Uint8Array) {
152
154
  const buf = Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer);
153
155
 
154
156
  // Uses the high-speed, non-cryptographic xxhash64 algorithm
@@ -160,7 +162,7 @@ export function defaultHash(buffer) {
160
162
  }
161
163
 
162
164
 
163
- export function memcmpEqual(buffer1, buffer2) {
165
+ export function memcmpEqual(buffer1: Buffer | Uint8Array, buffer2: Buffer | Uint8Array) {
164
166
  const b1 = Buffer.isBuffer(buffer1) ? buffer1 : Buffer.from(buffer1);
165
167
  const b2 = Buffer.isBuffer(buffer2) ? buffer2 : Buffer.from(buffer2);
166
168
 
@@ -168,7 +170,7 @@ export function memcmpEqual(buffer1, buffer2) {
168
170
  }
169
171
 
170
172
 
171
- export function arrayBufferToString(buffer) {
173
+ export function arrayBufferToString(buffer: Buffer | Uint8Array) {
172
174
  const buf = Buffer.isBuffer(buffer) ? buffer : Buffer.from(buffer);
173
175
 
174
176
  // Decodes the buffer bytes as a UTF-8 JavaScript string
@@ -180,7 +182,7 @@ export function arrayBufferToString(buffer) {
180
182
 
181
183
 
182
184
  // Matches QString Response::getSliceAsText
183
- export function getSliceAsText(rawTextBuffer, offset: number, length: number): string {
185
+ export function getSliceAsText(rawTextBuffer: Buffer, offset: number, length: number): string {
184
186
  // Reuses the identical slice boundary logic from above
185
187
  try {
186
188
  const slice = getSliceAsArrayBuffer(rawTextBuffer, offset, length);
@@ -191,7 +193,7 @@ export function getSliceAsText(rawTextBuffer, offset: number, length: number): s
191
193
  }
192
194
 
193
195
  // Matches QByteArray Response::getSliceAsArrayBuffer
194
- export function getSliceAsArrayBuffer(rawTextBuffer, offset: number, length: number): Buffer {
196
+ export function getSliceAsArrayBuffer(rawTextBuffer: Buffer, offset: number, length: number): Buffer {
195
197
  const totalSize = rawTextBuffer.length;
196
198
 
197
199
  if (offset < 0 || offset >= totalSize) {
@@ -1,4 +1,4 @@
1
- import {getNormalizedBounds, type Bounds} from './index.ts'
1
+ import {getNormalizedBounds, type AbsoluteBounds} from './index.ts'
2
2
  import {addUTCYears, addUTCMonths, addUTCDays} from '../../utils.ts'
3
3
 
4
4
 
@@ -6,7 +6,7 @@ const MONTH_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Se
6
6
  const MONTH_LONG = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
7
7
 
8
8
 
9
- export function formatDate(value, format) {
9
+ export function formatDate(value: string | number | Date, format: string) {
10
10
 
11
11
  const dateObj = value instanceof Date ? value : new Date(value)
12
12
 
@@ -59,7 +59,7 @@ export function formatDate(value, format) {
59
59
  D: () => dates.join(separator),
60
60
  };
61
61
 
62
- return format.replace(/YYYY|MMMM|MMM|YY|MM|DD|D/g, token => replacements[token]());
62
+ return format.replace(/YYYY|MMMM|MMM|YY|MM|DD|D/g, token => replacements[token as keyof typeof replacements]());
63
63
  }
64
64
 
65
65
 
@@ -83,7 +83,7 @@ export function formatDate(value, format) {
83
83
 
84
84
 
85
85
 
86
- export function fillDates(bounds_t, format) {
86
+ export function fillDates(bounds_t: AbsoluteBounds, format: string) {
87
87
  const result = [];
88
88
 
89
89
  let step;
@@ -94,11 +94,11 @@ export function fillDates(bounds_t, format) {
94
94
  else
95
95
  step = "year";
96
96
 
97
- let bounds: Bounds = { ...bounds_t, from: new Date(bounds_t.from), to: new Date(bounds_t.to) }
97
+ let bounds: AbsoluteBounds = { ...bounds_t, from: new Date(bounds_t.from), to: new Date(bounds_t.to) }
98
98
 
99
99
  bounds = getNormalizedBounds(bounds, "date")
100
100
 
101
- while (bounds.from <= bounds.to) {
101
+ while (bounds.from! <= bounds.to!) {
102
102
  result.push(formatDate(bounds.from, format));
103
103
 
104
104
  switch (step) {
@@ -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
- function flatten_id_values(target_key, values) {
5
- let flattened = [];
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 value of values) {
106
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
107
- other.push(value);
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
- export type Bounds = {
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 value of values) {
183
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
184
- remaining.push(value);
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: Bounds, type): Bounds {
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 = Math.max(aFrom, bFrom);
17
- const right = Math.min(aTo, bTo);
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, any>) {
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, collections, query, insertMode?: boolean, arg?: Arg) {
141
- collections = Array.isArray(collections) ? collections : [collections]
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 ?? []