@arcote.tech/arc-adapter-db-sqlite 0.7.27 → 0.7.29
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/index.js +172 -35
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1832,9 +1832,12 @@ class LocalEventPublisher {
|
|
|
1832
1832
|
store: EVENT_TABLES.events,
|
|
1833
1833
|
changes: [{ type: "set", data: storedEvent }]
|
|
1834
1834
|
});
|
|
1835
|
-
|
|
1835
|
+
const tagFields = event.definition?.tagFields ?? [];
|
|
1836
|
+
if (tagFields.length > 0 && event.payload && typeof event.payload === "object") {
|
|
1837
|
+
const payload = event.payload;
|
|
1836
1838
|
const tagChanges = [];
|
|
1837
|
-
for (const
|
|
1839
|
+
for (const key of tagFields) {
|
|
1840
|
+
const value = payload[key];
|
|
1838
1841
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1839
1842
|
tagChanges.push({
|
|
1840
1843
|
type: "set",
|
|
@@ -2058,6 +2061,11 @@ class ArcOptional {
|
|
|
2058
2061
|
return false;
|
|
2059
2062
|
return this.parent.validate(value);
|
|
2060
2063
|
}
|
|
2064
|
+
coerce(value) {
|
|
2065
|
+
if (value == null)
|
|
2066
|
+
return;
|
|
2067
|
+
return this.parent.coerce(value);
|
|
2068
|
+
}
|
|
2061
2069
|
toJsonSchema() {
|
|
2062
2070
|
const parentSchema = this.parent.toJsonSchema?.() ?? {};
|
|
2063
2071
|
return {
|
|
@@ -2104,6 +2112,9 @@ class ArcBranded {
|
|
|
2104
2112
|
validate(value) {
|
|
2105
2113
|
return this.parent.validate(value);
|
|
2106
2114
|
}
|
|
2115
|
+
coerce(value) {
|
|
2116
|
+
return this.parent.coerce(value);
|
|
2117
|
+
}
|
|
2107
2118
|
toJsonSchema() {
|
|
2108
2119
|
return this.parent.toJsonSchema?.() ?? {};
|
|
2109
2120
|
}
|
|
@@ -2128,6 +2139,11 @@ class ArcDefault {
|
|
|
2128
2139
|
return false;
|
|
2129
2140
|
return this.parent.validate(value);
|
|
2130
2141
|
}
|
|
2142
|
+
coerce(value) {
|
|
2143
|
+
if (value === undefined || value === null)
|
|
2144
|
+
return;
|
|
2145
|
+
return this.parent.coerce(value);
|
|
2146
|
+
}
|
|
2131
2147
|
parse(value) {
|
|
2132
2148
|
if (value)
|
|
2133
2149
|
return this.parent.parse(value);
|
|
@@ -2210,6 +2226,9 @@ class ArcAbstract {
|
|
|
2210
2226
|
}
|
|
2211
2227
|
return false;
|
|
2212
2228
|
}
|
|
2229
|
+
coerce(value) {
|
|
2230
|
+
return this.validate(value) ? undefined : value;
|
|
2231
|
+
}
|
|
2213
2232
|
pipeValidation(name, validator) {
|
|
2214
2233
|
const newInstance = this.clone();
|
|
2215
2234
|
newInstance.validations = [...this.validations, { name, validator }];
|
|
@@ -2347,6 +2366,17 @@ class ArcArray extends ArcAbstract {
|
|
|
2347
2366
|
return { msg: "array is empty" };
|
|
2348
2367
|
});
|
|
2349
2368
|
}
|
|
2369
|
+
coerce(value) {
|
|
2370
|
+
if (!Array.isArray(value))
|
|
2371
|
+
return;
|
|
2372
|
+
const out = [];
|
|
2373
|
+
for (const item of value) {
|
|
2374
|
+
const coerced = this.parent.coerce(item);
|
|
2375
|
+
if (coerced !== undefined)
|
|
2376
|
+
out.push(coerced);
|
|
2377
|
+
}
|
|
2378
|
+
return this.validate(out) ? undefined : out;
|
|
2379
|
+
}
|
|
2350
2380
|
parse(value) {
|
|
2351
2381
|
return value.map((v) => this.parent.parse(v));
|
|
2352
2382
|
}
|
|
@@ -2418,6 +2448,19 @@ class ArcObject extends ArcAbstract {
|
|
|
2418
2448
|
]);
|
|
2419
2449
|
this.rawShape = rawShape;
|
|
2420
2450
|
}
|
|
2451
|
+
coerce(value) {
|
|
2452
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
2453
|
+
return;
|
|
2454
|
+
}
|
|
2455
|
+
const src = value;
|
|
2456
|
+
const out = {};
|
|
2457
|
+
for (const [key, element] of Object.entries(this.rawShape)) {
|
|
2458
|
+
const coerced = element.coerce(src[key]);
|
|
2459
|
+
if (coerced !== undefined)
|
|
2460
|
+
out[key] = coerced;
|
|
2461
|
+
}
|
|
2462
|
+
return this.validate(out) ? undefined : out;
|
|
2463
|
+
}
|
|
2421
2464
|
parse(value) {
|
|
2422
2465
|
return Object.entries(this.rawShape).reduce((acc, [key, element]) => {
|
|
2423
2466
|
acc[key] = element.parse(value[key]);
|
|
@@ -2667,6 +2710,25 @@ class ArcAuthorizationError extends Error {
|
|
|
2667
2710
|
this.name = "ArcAuthorizationError";
|
|
2668
2711
|
}
|
|
2669
2712
|
}
|
|
2713
|
+
function collectFieldPaths(errors, prefix = "") {
|
|
2714
|
+
if (!errors || typeof errors !== "object")
|
|
2715
|
+
return [];
|
|
2716
|
+
const schema = errors.schema;
|
|
2717
|
+
if (!schema || typeof schema !== "object")
|
|
2718
|
+
return [];
|
|
2719
|
+
const out = [];
|
|
2720
|
+
for (const [field, fieldError] of Object.entries(schema)) {
|
|
2721
|
+
if (!fieldError)
|
|
2722
|
+
continue;
|
|
2723
|
+
const path = prefix ? `${prefix}.${field}` : field;
|
|
2724
|
+
const nested = collectFieldPaths(fieldError, path);
|
|
2725
|
+
if (nested.length > 0)
|
|
2726
|
+
out.push(...nested);
|
|
2727
|
+
else
|
|
2728
|
+
out.push(path);
|
|
2729
|
+
}
|
|
2730
|
+
return out;
|
|
2731
|
+
}
|
|
2670
2732
|
|
|
2671
2733
|
class ArcValidationError extends Error {
|
|
2672
2734
|
arcCode = "VALIDATION";
|
|
@@ -2674,7 +2736,8 @@ class ArcValidationError extends Error {
|
|
|
2674
2736
|
constructor(errors, message = "Invalid parameters") {
|
|
2675
2737
|
super(message);
|
|
2676
2738
|
this.name = "ArcValidationError";
|
|
2677
|
-
|
|
2739
|
+
const paths = collectFieldPaths(errors);
|
|
2740
|
+
this.fields = paths.length > 0 ? paths : errors && typeof errors === "object" ? Object.keys(errors) : [];
|
|
2678
2741
|
}
|
|
2679
2742
|
}
|
|
2680
2743
|
class ArcPrimitive extends ArcAbstract {
|
|
@@ -2851,12 +2914,35 @@ class ArcContextElement extends ArcFragmentBase {
|
|
|
2851
2914
|
types = ["context-element"];
|
|
2852
2915
|
__contextId;
|
|
2853
2916
|
__contextName;
|
|
2917
|
+
__contextPath;
|
|
2854
2918
|
get id() {
|
|
2855
2919
|
return this.name;
|
|
2856
2920
|
}
|
|
2921
|
+
__declStack;
|
|
2857
2922
|
constructor(name) {
|
|
2858
2923
|
super();
|
|
2859
2924
|
this.name = name;
|
|
2925
|
+
this.__declStack = new Error().stack;
|
|
2926
|
+
}
|
|
2927
|
+
getSourceLocation() {
|
|
2928
|
+
const stack = this.__declStack;
|
|
2929
|
+
if (!stack)
|
|
2930
|
+
return;
|
|
2931
|
+
for (const raw of stack.split(`
|
|
2932
|
+
`).slice(1)) {
|
|
2933
|
+
const m = raw.match(/\(?((?:file:\/\/)?[^()\s]+?):(\d+):(\d+)\)?$/);
|
|
2934
|
+
if (!m)
|
|
2935
|
+
continue;
|
|
2936
|
+
let file = m[1];
|
|
2937
|
+
if (file.startsWith("file://"))
|
|
2938
|
+
file = file.slice(7);
|
|
2939
|
+
const isCoreInternal = /packages\/core\/(src|dist)\//.test(file) && !/\.test\.tsx?$/.test(file);
|
|
2940
|
+
if (file.includes("node_modules") || isCoreInternal || file.includes("native:") || !file.includes("/")) {
|
|
2941
|
+
continue;
|
|
2942
|
+
}
|
|
2943
|
+
return { file, line: Number(m[2]) };
|
|
2944
|
+
}
|
|
2945
|
+
return;
|
|
2860
2946
|
}
|
|
2861
2947
|
_seeds;
|
|
2862
2948
|
getSeeds() {
|
|
@@ -3041,7 +3127,8 @@ class ArcEvent extends ArcContextElement {
|
|
|
3041
3127
|
payload,
|
|
3042
3128
|
id: this.eventId.generate(),
|
|
3043
3129
|
createdAt: new Date,
|
|
3044
|
-
authContext
|
|
3130
|
+
authContext,
|
|
3131
|
+
definition: this
|
|
3045
3132
|
};
|
|
3046
3133
|
await adapters.eventPublisher.publish(event);
|
|
3047
3134
|
}
|
|
@@ -3094,8 +3181,8 @@ class ArcEvent extends ArcContextElement {
|
|
|
3094
3181
|
const tagsSchema = new ArcObject({
|
|
3095
3182
|
_id: new ArcString().primaryKey(),
|
|
3096
3183
|
eventId: new ArcString().index(),
|
|
3097
|
-
tagKey: new ArcString
|
|
3098
|
-
tagValue: new ArcString
|
|
3184
|
+
tagKey: new ArcString,
|
|
3185
|
+
tagValue: new ArcString
|
|
3099
3186
|
});
|
|
3100
3187
|
const syncStatusSchema = new ArcObject({
|
|
3101
3188
|
_id: new ArcString().primaryKey(),
|
|
@@ -3237,6 +3324,34 @@ class ArcFunction {
|
|
|
3237
3324
|
};
|
|
3238
3325
|
}
|
|
3239
3326
|
}
|
|
3327
|
+
function serializeParams(schema, params) {
|
|
3328
|
+
if (schema && typeof schema.serialize === "function") {
|
|
3329
|
+
return schema.serialize(params ?? {});
|
|
3330
|
+
}
|
|
3331
|
+
return params;
|
|
3332
|
+
}
|
|
3333
|
+
function deserializeParams(schema, params) {
|
|
3334
|
+
if (schema && typeof schema.deserialize === "function") {
|
|
3335
|
+
return schema.deserialize(params ?? {});
|
|
3336
|
+
}
|
|
3337
|
+
return params;
|
|
3338
|
+
}
|
|
3339
|
+
function deserializeResult(schemas, value) {
|
|
3340
|
+
const list = Array.isArray(schemas) ? schemas : undefined;
|
|
3341
|
+
if (!list || list.length !== 1)
|
|
3342
|
+
return value;
|
|
3343
|
+
const schema = list[0];
|
|
3344
|
+
if (!schema || typeof schema.deserialize !== "function")
|
|
3345
|
+
return value;
|
|
3346
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
3347
|
+
return value;
|
|
3348
|
+
}
|
|
3349
|
+
try {
|
|
3350
|
+
return schema.deserialize(value);
|
|
3351
|
+
} catch {
|
|
3352
|
+
return value;
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3240
3355
|
class AggregateBase {
|
|
3241
3356
|
value;
|
|
3242
3357
|
_id;
|
|
@@ -3363,7 +3478,8 @@ class ArcCommand extends ArcContextElement {
|
|
|
3363
3478
|
scope: adapters.scope.scopeName,
|
|
3364
3479
|
token: adapters.scope.getToken()
|
|
3365
3480
|
} : undefined;
|
|
3366
|
-
|
|
3481
|
+
const wireResult = await adapters.commandWire.executeCommand(this.data.name, serializeParams(this.data.params, params), wireAuth);
|
|
3482
|
+
return deserializeResult(this.data.results, wireResult);
|
|
3367
3483
|
};
|
|
3368
3484
|
return Object.assign(executeFunc, { params: this.data.params });
|
|
3369
3485
|
}
|
|
@@ -3371,10 +3487,11 @@ class ArcCommand extends ArcContextElement {
|
|
|
3371
3487
|
if (!this.data.handler) {
|
|
3372
3488
|
throw new Error(`Command "${this.data.name}" has no handler`);
|
|
3373
3489
|
}
|
|
3374
|
-
this
|
|
3490
|
+
const input = deserializeParams(this.data.params, params);
|
|
3491
|
+
this.#fn.validateParams(input);
|
|
3375
3492
|
await this.#fn.authorize(adapters);
|
|
3376
3493
|
const context2 = this.buildCommandContext(adapters);
|
|
3377
|
-
return await this.data.handler(context2,
|
|
3494
|
+
return await this.data.handler(context2, input);
|
|
3378
3495
|
}
|
|
3379
3496
|
buildCommandContext(adapters) {
|
|
3380
3497
|
const context2 = this.#fn.buildContext(adapters);
|
|
@@ -4036,16 +4153,57 @@ function resolveQueryChange(currentResult, event3, options) {
|
|
|
4036
4153
|
}
|
|
4037
4154
|
const shouldBeInResult = checkItemMatchesWhere(event3.item, options.where);
|
|
4038
4155
|
if (isInCurrentResult && shouldBeInResult) {
|
|
4039
|
-
|
|
4040
|
-
|
|
4156
|
+
if (!options.orderBy) {
|
|
4157
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
4158
|
+
}
|
|
4159
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
4160
|
+
if (cmp(currentResult[index], event3.item) === 0) {
|
|
4161
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
4162
|
+
}
|
|
4163
|
+
const without = currentResult.toSpliced(index, 1);
|
|
4164
|
+
const at = upperBound(without, event3.item, cmp);
|
|
4165
|
+
return applyLimit(without.toSpliced(at, 0, event3.item), options);
|
|
4041
4166
|
} else if (isInCurrentResult && !shouldBeInResult) {
|
|
4042
4167
|
return currentResult.toSpliced(index, 1);
|
|
4043
4168
|
} else if (!isInCurrentResult && shouldBeInResult) {
|
|
4044
|
-
|
|
4045
|
-
|
|
4169
|
+
if (!options.orderBy) {
|
|
4170
|
+
return applyLimit([...currentResult, event3.item], options);
|
|
4171
|
+
}
|
|
4172
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
4173
|
+
const at = upperBound(currentResult, event3.item, cmp);
|
|
4174
|
+
return applyLimit(currentResult.toSpliced(at, 0, event3.item), options);
|
|
4046
4175
|
}
|
|
4047
4176
|
return false;
|
|
4048
4177
|
}
|
|
4178
|
+
function compareByOrderBy(orderBy) {
|
|
4179
|
+
const entries = Object.entries(orderBy);
|
|
4180
|
+
return (a, b) => {
|
|
4181
|
+
for (const [key, direction] of entries) {
|
|
4182
|
+
const aVal = a[key];
|
|
4183
|
+
const bVal = b[key];
|
|
4184
|
+
if (aVal < bVal)
|
|
4185
|
+
return direction === "asc" ? -1 : 1;
|
|
4186
|
+
if (aVal > bVal)
|
|
4187
|
+
return direction === "asc" ? 1 : -1;
|
|
4188
|
+
}
|
|
4189
|
+
return 0;
|
|
4190
|
+
};
|
|
4191
|
+
}
|
|
4192
|
+
function upperBound(arr, item, cmp) {
|
|
4193
|
+
let lo = 0;
|
|
4194
|
+
let hi = arr.length;
|
|
4195
|
+
while (lo < hi) {
|
|
4196
|
+
const mid = lo + hi >> 1;
|
|
4197
|
+
if (cmp(arr[mid], item) <= 0)
|
|
4198
|
+
lo = mid + 1;
|
|
4199
|
+
else
|
|
4200
|
+
hi = mid;
|
|
4201
|
+
}
|
|
4202
|
+
return lo;
|
|
4203
|
+
}
|
|
4204
|
+
function applyLimit(result, options) {
|
|
4205
|
+
return options.limit !== undefined && result.length > options.limit ? result.slice(0, options.limit) : result;
|
|
4206
|
+
}
|
|
4049
4207
|
function checkItemMatchesWhere(item, where) {
|
|
4050
4208
|
if (!where) {
|
|
4051
4209
|
return true;
|
|
@@ -4081,27 +4239,6 @@ function checkItemMatchesWhere(item, where) {
|
|
|
4081
4239
|
});
|
|
4082
4240
|
});
|
|
4083
4241
|
}
|
|
4084
|
-
function applyOrderByAndLimit(result, options) {
|
|
4085
|
-
let sorted = result;
|
|
4086
|
-
if (options.orderBy) {
|
|
4087
|
-
sorted = [...result].sort((a, b) => {
|
|
4088
|
-
for (const [key, direction] of Object.entries(options.orderBy)) {
|
|
4089
|
-
const aVal = a[key];
|
|
4090
|
-
const bVal = b[key];
|
|
4091
|
-
if (aVal < bVal)
|
|
4092
|
-
return direction === "asc" ? -1 : 1;
|
|
4093
|
-
if (aVal > bVal)
|
|
4094
|
-
return direction === "asc" ? 1 : -1;
|
|
4095
|
-
}
|
|
4096
|
-
return 0;
|
|
4097
|
-
});
|
|
4098
|
-
}
|
|
4099
|
-
if (options.limit !== undefined) {
|
|
4100
|
-
sorted = sorted.slice(0, options.limit);
|
|
4101
|
-
}
|
|
4102
|
-
return sorted;
|
|
4103
|
-
}
|
|
4104
|
-
|
|
4105
4242
|
class ObservableDataStorage {
|
|
4106
4243
|
source;
|
|
4107
4244
|
onChange;
|
|
@@ -4257,7 +4394,7 @@ function extractDatabaseAgnosticSchema(arcObject, tableName) {
|
|
|
4257
4394
|
columns
|
|
4258
4395
|
};
|
|
4259
4396
|
}
|
|
4260
|
-
var dateValidator = typeValidatorBuilder("Date", (value) => value instanceof Date);
|
|
4397
|
+
var dateValidator = typeValidatorBuilder("Date", (value) => value instanceof Date && !isNaN(value.getTime()));
|
|
4261
4398
|
function buildContextAccessor(context2, adapters, contextMethod, onCall) {
|
|
4262
4399
|
const result = {};
|
|
4263
4400
|
for (const element2 of context2.elements) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc-adapter-db-sqlite",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"test": "bun test"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@arcote.tech/arc": "^0.7.
|
|
23
|
+
"@arcote.tech/arc": "^0.7.29"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"typescript": "^5.0.0"
|