@arcote.tech/arc-cli 0.7.27 → 0.7.28
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 +493 -171
- package/package.json +10 -10
- package/src/platform/server.ts +31 -6
package/dist/index.js
CHANGED
|
@@ -9634,6 +9634,7 @@ var exports_dist2 = {};
|
|
|
9634
9634
|
__export(exports_dist2, {
|
|
9635
9635
|
createPostgreSQLAdapterFactoryFromUrl: () => createPostgreSQLAdapterFactoryFromUrl,
|
|
9636
9636
|
createPostgreSQLAdapterFactory: () => createPostgreSQLAdapterFactory,
|
|
9637
|
+
coercePgNumber: () => coercePgNumber,
|
|
9637
9638
|
PostgreSQLAdapter: () => PostgreSQLAdapter
|
|
9638
9639
|
});
|
|
9639
9640
|
import os2 from "os";
|
|
@@ -10866,9 +10867,21 @@ class LocalEventPublisher2 {
|
|
|
10866
10867
|
views = [];
|
|
10867
10868
|
syncCallback;
|
|
10868
10869
|
subscribers = new Map;
|
|
10870
|
+
pending = new Set;
|
|
10869
10871
|
constructor(dataStorage) {
|
|
10870
10872
|
this.dataStorage = dataStorage;
|
|
10871
10873
|
}
|
|
10874
|
+
track(work) {
|
|
10875
|
+
const wrapped = Promise.resolve(work).catch(() => {}).finally(() => {
|
|
10876
|
+
this.pending.delete(wrapped);
|
|
10877
|
+
});
|
|
10878
|
+
this.pending.add(wrapped);
|
|
10879
|
+
}
|
|
10880
|
+
async whenIdle() {
|
|
10881
|
+
while (this.pending.size > 0) {
|
|
10882
|
+
await Promise.all([...this.pending]);
|
|
10883
|
+
}
|
|
10884
|
+
}
|
|
10872
10885
|
onPublish(callback) {
|
|
10873
10886
|
this.syncCallback = callback;
|
|
10874
10887
|
}
|
|
@@ -10904,9 +10917,12 @@ class LocalEventPublisher2 {
|
|
|
10904
10917
|
store: EVENT_TABLES.events,
|
|
10905
10918
|
changes: [{ type: "set", data: storedEvent }]
|
|
10906
10919
|
});
|
|
10907
|
-
|
|
10920
|
+
const tagFields = event.definition?.tagFields ?? [];
|
|
10921
|
+
if (tagFields.length > 0 && event.payload && typeof event.payload === "object") {
|
|
10922
|
+
const payload = event.payload;
|
|
10908
10923
|
const tagChanges = [];
|
|
10909
|
-
for (const
|
|
10924
|
+
for (const key of tagFields) {
|
|
10925
|
+
const value = payload[key];
|
|
10910
10926
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
10911
10927
|
tagChanges.push({
|
|
10912
10928
|
type: "set",
|
|
@@ -11064,6 +11080,47 @@ class LocalEventPublisher2 {
|
|
|
11064
11080
|
return allViewChanges;
|
|
11065
11081
|
}
|
|
11066
11082
|
}
|
|
11083
|
+
function murmurHash(key, seed = 0) {
|
|
11084
|
+
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
11085
|
+
remainder = key.length & 3;
|
|
11086
|
+
bytes = key.length - remainder;
|
|
11087
|
+
h1 = seed;
|
|
11088
|
+
c1 = 3432918353;
|
|
11089
|
+
c2 = 461845907;
|
|
11090
|
+
i = 0;
|
|
11091
|
+
while (i < bytes) {
|
|
11092
|
+
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
11093
|
+
++i;
|
|
11094
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
11095
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
11096
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
11097
|
+
h1 ^= k1;
|
|
11098
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
11099
|
+
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
11100
|
+
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
11101
|
+
}
|
|
11102
|
+
k1 = 0;
|
|
11103
|
+
if (remainder >= 3) {
|
|
11104
|
+
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
11105
|
+
}
|
|
11106
|
+
if (remainder >= 2) {
|
|
11107
|
+
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
11108
|
+
}
|
|
11109
|
+
if (remainder >= 1) {
|
|
11110
|
+
k1 ^= key.charCodeAt(i) & 255;
|
|
11111
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
11112
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
11113
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
11114
|
+
h1 ^= k1;
|
|
11115
|
+
}
|
|
11116
|
+
h1 ^= key.length;
|
|
11117
|
+
h1 ^= h1 >>> 16;
|
|
11118
|
+
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
11119
|
+
h1 ^= h1 >>> 13;
|
|
11120
|
+
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
11121
|
+
h1 ^= h1 >>> 16;
|
|
11122
|
+
return h1 >>> 0;
|
|
11123
|
+
}
|
|
11067
11124
|
|
|
11068
11125
|
class ArcOptional {
|
|
11069
11126
|
parent;
|
|
@@ -11156,7 +11213,9 @@ class ArcDefault {
|
|
|
11156
11213
|
this.defaultValueOrCallback = defaultValueOrCallback;
|
|
11157
11214
|
}
|
|
11158
11215
|
validate(value) {
|
|
11159
|
-
|
|
11216
|
+
if (value === undefined || value === null)
|
|
11217
|
+
return false;
|
|
11218
|
+
return this.parent.validate(value);
|
|
11160
11219
|
}
|
|
11161
11220
|
parse(value) {
|
|
11162
11221
|
if (value)
|
|
@@ -11393,6 +11452,25 @@ class ScopedStore {
|
|
|
11393
11452
|
}
|
|
11394
11453
|
}
|
|
11395
11454
|
}
|
|
11455
|
+
function collectFieldPaths(errors, prefix = "") {
|
|
11456
|
+
if (!errors || typeof errors !== "object")
|
|
11457
|
+
return [];
|
|
11458
|
+
const schema = errors.schema;
|
|
11459
|
+
if (!schema || typeof schema !== "object")
|
|
11460
|
+
return [];
|
|
11461
|
+
const out = [];
|
|
11462
|
+
for (const [field, fieldError] of Object.entries(schema)) {
|
|
11463
|
+
if (!fieldError)
|
|
11464
|
+
continue;
|
|
11465
|
+
const path4 = prefix ? `${prefix}.${field}` : field;
|
|
11466
|
+
const nested = collectFieldPaths(fieldError, path4);
|
|
11467
|
+
if (nested.length > 0)
|
|
11468
|
+
out.push(...nested);
|
|
11469
|
+
else
|
|
11470
|
+
out.push(path4);
|
|
11471
|
+
}
|
|
11472
|
+
return out;
|
|
11473
|
+
}
|
|
11396
11474
|
function string() {
|
|
11397
11475
|
return new ArcString;
|
|
11398
11476
|
}
|
|
@@ -11527,6 +11605,27 @@ class ArcFunction {
|
|
|
11527
11605
|
get results() {
|
|
11528
11606
|
return this.data.results;
|
|
11529
11607
|
}
|
|
11608
|
+
validateParams(params) {
|
|
11609
|
+
const schema = this.data.params;
|
|
11610
|
+
if (!schema || typeof schema.validate !== "function")
|
|
11611
|
+
return;
|
|
11612
|
+
const errors = schema.validate(params ?? {});
|
|
11613
|
+
if (errors)
|
|
11614
|
+
throw new ArcValidationError2(errors);
|
|
11615
|
+
}
|
|
11616
|
+
async authorize(adapters) {
|
|
11617
|
+
if (!this.hasProtections)
|
|
11618
|
+
return;
|
|
11619
|
+
const decoded = adapters.authAdapter?.getDecoded?.();
|
|
11620
|
+
if (!decoded) {
|
|
11621
|
+
throw new ArcAuthenticationError;
|
|
11622
|
+
}
|
|
11623
|
+
const instances = this.data.protections.filter((p3) => p3.token?.name === decoded.tokenName).map((p3) => p3.token.create(decoded.params, adapters));
|
|
11624
|
+
const ok2 = await this.verifyProtections(instances);
|
|
11625
|
+
if (!ok2) {
|
|
11626
|
+
throw new ArcAuthorizationError2;
|
|
11627
|
+
}
|
|
11628
|
+
}
|
|
11530
11629
|
async verifyProtections(tokens) {
|
|
11531
11630
|
if (!this.data.protections || this.data.protections.length === 0) {
|
|
11532
11631
|
return true;
|
|
@@ -11678,47 +11777,6 @@ function deepMerge(target, source) {
|
|
|
11678
11777
|
function isPlainObject(item) {
|
|
11679
11778
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
11680
11779
|
}
|
|
11681
|
-
function murmurHash(key, seed = 0) {
|
|
11682
|
-
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
11683
|
-
remainder = key.length & 3;
|
|
11684
|
-
bytes = key.length - remainder;
|
|
11685
|
-
h1 = seed;
|
|
11686
|
-
c1 = 3432918353;
|
|
11687
|
-
c2 = 461845907;
|
|
11688
|
-
i = 0;
|
|
11689
|
-
while (i < bytes) {
|
|
11690
|
-
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
11691
|
-
++i;
|
|
11692
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
11693
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
11694
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
11695
|
-
h1 ^= k1;
|
|
11696
|
-
h1 = h1 << 13 | h1 >>> 19;
|
|
11697
|
-
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
11698
|
-
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
11699
|
-
}
|
|
11700
|
-
k1 = 0;
|
|
11701
|
-
if (remainder >= 3) {
|
|
11702
|
-
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
11703
|
-
}
|
|
11704
|
-
if (remainder >= 2) {
|
|
11705
|
-
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
11706
|
-
}
|
|
11707
|
-
if (remainder >= 1) {
|
|
11708
|
-
k1 ^= key.charCodeAt(i) & 255;
|
|
11709
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
11710
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
11711
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
11712
|
-
h1 ^= k1;
|
|
11713
|
-
}
|
|
11714
|
-
h1 ^= key.length;
|
|
11715
|
-
h1 ^= h1 >>> 16;
|
|
11716
|
-
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
11717
|
-
h1 ^= h1 >>> 13;
|
|
11718
|
-
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
11719
|
-
h1 ^= h1 >>> 16;
|
|
11720
|
-
return h1 >>> 0;
|
|
11721
|
-
}
|
|
11722
11780
|
function resolveQueryChange(currentResult, event3, options) {
|
|
11723
11781
|
const index = currentResult.findIndex((e2) => e2._id === event3.id);
|
|
11724
11782
|
const isInCurrentResult = index !== -1;
|
|
@@ -11730,16 +11788,57 @@ function resolveQueryChange(currentResult, event3, options) {
|
|
|
11730
11788
|
}
|
|
11731
11789
|
const shouldBeInResult = checkItemMatchesWhere(event3.item, options.where);
|
|
11732
11790
|
if (isInCurrentResult && shouldBeInResult) {
|
|
11733
|
-
|
|
11734
|
-
|
|
11791
|
+
if (!options.orderBy) {
|
|
11792
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
11793
|
+
}
|
|
11794
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
11795
|
+
if (cmp(currentResult[index], event3.item) === 0) {
|
|
11796
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
11797
|
+
}
|
|
11798
|
+
const without = currentResult.toSpliced(index, 1);
|
|
11799
|
+
const at = upperBound(without, event3.item, cmp);
|
|
11800
|
+
return applyLimit(without.toSpliced(at, 0, event3.item), options);
|
|
11735
11801
|
} else if (isInCurrentResult && !shouldBeInResult) {
|
|
11736
11802
|
return currentResult.toSpliced(index, 1);
|
|
11737
11803
|
} else if (!isInCurrentResult && shouldBeInResult) {
|
|
11738
|
-
|
|
11739
|
-
|
|
11804
|
+
if (!options.orderBy) {
|
|
11805
|
+
return applyLimit([...currentResult, event3.item], options);
|
|
11806
|
+
}
|
|
11807
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
11808
|
+
const at = upperBound(currentResult, event3.item, cmp);
|
|
11809
|
+
return applyLimit(currentResult.toSpliced(at, 0, event3.item), options);
|
|
11740
11810
|
}
|
|
11741
11811
|
return false;
|
|
11742
11812
|
}
|
|
11813
|
+
function compareByOrderBy(orderBy) {
|
|
11814
|
+
const entries = Object.entries(orderBy);
|
|
11815
|
+
return (a2, b3) => {
|
|
11816
|
+
for (const [key, direction] of entries) {
|
|
11817
|
+
const aVal = a2[key];
|
|
11818
|
+
const bVal = b3[key];
|
|
11819
|
+
if (aVal < bVal)
|
|
11820
|
+
return direction === "asc" ? -1 : 1;
|
|
11821
|
+
if (aVal > bVal)
|
|
11822
|
+
return direction === "asc" ? 1 : -1;
|
|
11823
|
+
}
|
|
11824
|
+
return 0;
|
|
11825
|
+
};
|
|
11826
|
+
}
|
|
11827
|
+
function upperBound(arr, item, cmp) {
|
|
11828
|
+
let lo = 0;
|
|
11829
|
+
let hi = arr.length;
|
|
11830
|
+
while (lo < hi) {
|
|
11831
|
+
const mid = lo + hi >> 1;
|
|
11832
|
+
if (cmp(arr[mid], item) <= 0)
|
|
11833
|
+
lo = mid + 1;
|
|
11834
|
+
else
|
|
11835
|
+
hi = mid;
|
|
11836
|
+
}
|
|
11837
|
+
return lo;
|
|
11838
|
+
}
|
|
11839
|
+
function applyLimit(result, options) {
|
|
11840
|
+
return options.limit !== undefined && result.length > options.limit ? result.slice(0, options.limit) : result;
|
|
11841
|
+
}
|
|
11743
11842
|
function checkItemMatchesWhere(item, where) {
|
|
11744
11843
|
if (!where) {
|
|
11745
11844
|
return true;
|
|
@@ -11775,26 +11874,6 @@ function checkItemMatchesWhere(item, where) {
|
|
|
11775
11874
|
});
|
|
11776
11875
|
});
|
|
11777
11876
|
}
|
|
11778
|
-
function applyOrderByAndLimit(result, options) {
|
|
11779
|
-
let sorted = result;
|
|
11780
|
-
if (options.orderBy) {
|
|
11781
|
-
sorted = [...result].sort((a2, b3) => {
|
|
11782
|
-
for (const [key, direction] of Object.entries(options.orderBy)) {
|
|
11783
|
-
const aVal = a2[key];
|
|
11784
|
-
const bVal = b3[key];
|
|
11785
|
-
if (aVal < bVal)
|
|
11786
|
-
return direction === "asc" ? -1 : 1;
|
|
11787
|
-
if (aVal > bVal)
|
|
11788
|
-
return direction === "asc" ? 1 : -1;
|
|
11789
|
-
}
|
|
11790
|
-
return 0;
|
|
11791
|
-
});
|
|
11792
|
-
}
|
|
11793
|
-
if (options.limit !== undefined) {
|
|
11794
|
-
sorted = sorted.slice(0, options.limit);
|
|
11795
|
-
}
|
|
11796
|
-
return sorted;
|
|
11797
|
-
}
|
|
11798
11877
|
|
|
11799
11878
|
class ObservableDataStorage {
|
|
11800
11879
|
source;
|
|
@@ -12131,7 +12210,7 @@ class Model2 {
|
|
|
12131
12210
|
return s;
|
|
12132
12211
|
}
|
|
12133
12212
|
}
|
|
12134
|
-
function
|
|
12213
|
+
function applyQueryChanges2(result, changes) {
|
|
12135
12214
|
const next = [...result];
|
|
12136
12215
|
for (const change of changes) {
|
|
12137
12216
|
if (change.type === "delete") {
|
|
@@ -12184,7 +12263,7 @@ class StreamingQueryCache {
|
|
|
12184
12263
|
if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
|
|
12185
12264
|
return;
|
|
12186
12265
|
}
|
|
12187
|
-
newEntry.result =
|
|
12266
|
+
newEntry.result = applyQueryChanges2(newEntry.result, changes);
|
|
12188
12267
|
this.notify(newEntry);
|
|
12189
12268
|
}
|
|
12190
12269
|
});
|
|
@@ -14049,6 +14128,37 @@ function osUsername() {
|
|
|
14049
14128
|
return process.env.USERNAME || process.env.USER || process.env.LOGNAME;
|
|
14050
14129
|
}
|
|
14051
14130
|
}
|
|
14131
|
+
function unsafeIntMessage(raw, columnName) {
|
|
14132
|
+
const where = columnName ? ` w kolumnie "${columnName}"` : "";
|
|
14133
|
+
return `[PostgreSQL] Warto\u015B\u0107 ca\u0142kowita ${raw}${where} przekracza bezpieczny zakres ` + `JS Number (\xB12^53-1). Odczyt jako number cicho straci\u0142by precyzj\u0119. ` + `U\u017Cyj kolumny TEXT/NUMERIC i obs\u0142u\u017C warto\u015B\u0107 jako string/BigInt.`;
|
|
14134
|
+
}
|
|
14135
|
+
function coercePgNumber(value, columnName) {
|
|
14136
|
+
if (value === null || value === undefined)
|
|
14137
|
+
return value;
|
|
14138
|
+
if (typeof value === "number")
|
|
14139
|
+
return value;
|
|
14140
|
+
if (typeof value === "bigint") {
|
|
14141
|
+
if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) {
|
|
14142
|
+
throw new Error(unsafeIntMessage(value.toString(), columnName));
|
|
14143
|
+
}
|
|
14144
|
+
return Number(value);
|
|
14145
|
+
}
|
|
14146
|
+
if (typeof value === "string") {
|
|
14147
|
+
const s = value.trim();
|
|
14148
|
+
if (s === "")
|
|
14149
|
+
return value;
|
|
14150
|
+
if (/^[+-]?\d+$/.test(s)) {
|
|
14151
|
+
const big = BigInt(s);
|
|
14152
|
+
if (big > MAX_SAFE_INT || big < MIN_SAFE_INT) {
|
|
14153
|
+
throw new Error(unsafeIntMessage(s, columnName));
|
|
14154
|
+
}
|
|
14155
|
+
return Number(big);
|
|
14156
|
+
}
|
|
14157
|
+
const n2 = Number(s);
|
|
14158
|
+
return Number.isNaN(n2) ? value : n2;
|
|
14159
|
+
}
|
|
14160
|
+
return value;
|
|
14161
|
+
}
|
|
14052
14162
|
|
|
14053
14163
|
class PostgreSQLReadTransaction {
|
|
14054
14164
|
db;
|
|
@@ -14071,7 +14181,27 @@ class PostgreSQLReadTransaction {
|
|
|
14071
14181
|
deserializeValue(value, column) {
|
|
14072
14182
|
if (value === null || value === undefined)
|
|
14073
14183
|
return null;
|
|
14074
|
-
|
|
14184
|
+
const type = column.type.toLowerCase().split("(")[0].trim();
|
|
14185
|
+
switch (type) {
|
|
14186
|
+
case "bigint":
|
|
14187
|
+
case "int8":
|
|
14188
|
+
case "bigserial":
|
|
14189
|
+
case "serial8":
|
|
14190
|
+
case "serial":
|
|
14191
|
+
case "serial4":
|
|
14192
|
+
case "integer":
|
|
14193
|
+
case "int":
|
|
14194
|
+
case "int4":
|
|
14195
|
+
case "smallint":
|
|
14196
|
+
case "int2":
|
|
14197
|
+
case "numeric":
|
|
14198
|
+
case "decimal":
|
|
14199
|
+
case "real":
|
|
14200
|
+
case "double precision":
|
|
14201
|
+
case "float":
|
|
14202
|
+
case "float4":
|
|
14203
|
+
case "float8":
|
|
14204
|
+
return coercePgNumber(value, column.name);
|
|
14075
14205
|
case "json":
|
|
14076
14206
|
case "jsonb":
|
|
14077
14207
|
if (typeof value === "string") {
|
|
@@ -14667,7 +14797,7 @@ var Operation, PROXY_DRAFT, RAW_RETURN_SYMBOL, iteratorSymbol, dataTypes, intern
|
|
|
14667
14797
|
}
|
|
14668
14798
|
return returnValue(result);
|
|
14669
14799
|
};
|
|
14670
|
-
}, create, constructorString, TOKEN_PREFIX = "arc:token:", DEFAULT_TIMEOUT_MS = 8000, provider = null, latestSync = null, syncSeq = 0, eventWireInstanceCounter = 0, EVENT_TABLES, arrayValidator, ArcArray, objectValidator, ArcObject, ScopedDataStorage, ArcPrimitive, stringValidator, ArcString, ArcContextElement, ArcBoolean, ArcId, numberValidator, ArcNumber, ArcEvent, ArcCommand, ArcListener, ArcRoute, ForkedStoreState, ForkedDataStorage, MasterStoreState, MasterDataStorage2, dateValidator, originCache, originStackCache, originError, CLOSE, Query, PostgresError, Errors, types2, Identifier, Parameter, Builder, defaultHandlers, builders, serializers, parsers, mergeUserTypes = function(types22) {
|
|
14800
|
+
}, create, constructorString, TOKEN_PREFIX = "arc:token:", DEFAULT_TIMEOUT_MS = 8000, provider = null, latestSync = null, syncSeq = 0, eventWireInstanceCounter = 0, EVENT_TABLES, arrayValidator, ArcArray, objectValidator, ArcObject, ScopedDataStorage, ArcAuthenticationError, ArcAuthorizationError2, ArcValidationError2, ArcPrimitive, stringValidator, ArcString, ArcContextElement, ArcBoolean, ArcId, numberValidator, ArcNumber, ArcEvent, ArcCommand, ArcListener, ArcRoute, ForkedStoreState, ForkedDataStorage, MasterStoreState, MasterDataStorage2, dateValidator, _te, _td, originCache, originStackCache, originError, CLOSE, Query, PostgresError, Errors, types2, Identifier, Parameter, Builder, defaultHandlers, builders, serializers, parsers, mergeUserTypes = function(types22) {
|
|
14671
14801
|
const user = typeHandlers(types22 || {});
|
|
14672
14802
|
return {
|
|
14673
14803
|
serializers: Object.assign({}, serializers, user.serializers),
|
|
@@ -14707,7 +14837,7 @@ var Operation, PROXY_DRAFT, RAW_RETURN_SYMBOL, iteratorSymbol, dataTypes, intern
|
|
|
14707
14837
|
for (let i = 1;i < x2.length; i++)
|
|
14708
14838
|
str += x2[i] === "_" ? x2[++i].toUpperCase() : x2[i];
|
|
14709
14839
|
return str;
|
|
14710
|
-
}, toKebab = (x2) => x2.replace(/_/g, "-"), fromCamel = (x2) => x2.replace(/([A-Z])/g, "_$1").toLowerCase(), fromPascal = (x2) => (x2.slice(0, 1) + x2.slice(1).replace(/([A-Z])/g, "_$1")).toLowerCase(), fromKebab = (x2) => x2.replace(/-/g, "_"), camel, pascal, kebab, Result, queue_default, size = 256, buffer, messages, b3, bytes_default, connection_default, uid = 1, Sync, Flush, SSLRequest, ExecuteUnnamed, DescribeUnnamed, noop = () => {}, retryRoutines, errorFields, noop2 = () => {}, src_default, PostgreSQLReadWriteTransaction, createPostgreSQLAdapterFactory = (db) => {
|
|
14840
|
+
}, toKebab = (x2) => x2.replace(/_/g, "-"), fromCamel = (x2) => x2.replace(/([A-Z])/g, "_$1").toLowerCase(), fromPascal = (x2) => (x2.slice(0, 1) + x2.slice(1).replace(/([A-Z])/g, "_$1")).toLowerCase(), fromKebab = (x2) => x2.replace(/-/g, "_"), camel, pascal, kebab, Result, queue_default, size = 256, buffer, messages, b3, bytes_default, connection_default, uid = 1, Sync, Flush, SSLRequest, ExecuteUnnamed, DescribeUnnamed, noop = () => {}, retryRoutines, errorFields, noop2 = () => {}, src_default, MAX_SAFE_INT, MIN_SAFE_INT, PostgreSQLReadWriteTransaction, createPostgreSQLAdapterFactory = (db) => {
|
|
14711
14841
|
return async (context) => {
|
|
14712
14842
|
const adapter = new PostgreSQLAdapter(db, context);
|
|
14713
14843
|
await adapter.initialize();
|
|
@@ -14715,7 +14845,15 @@ var Operation, PROXY_DRAFT, RAW_RETURN_SYMBOL, iteratorSymbol, dataTypes, intern
|
|
|
14715
14845
|
};
|
|
14716
14846
|
}, createPostgreSQLAdapterFactoryFromUrl = (connectionString) => {
|
|
14717
14847
|
const sql = src_default(connectionString, {
|
|
14718
|
-
onnotice: () => {}
|
|
14848
|
+
onnotice: () => {},
|
|
14849
|
+
types: {
|
|
14850
|
+
bigint: {
|
|
14851
|
+
to: 20,
|
|
14852
|
+
from: [20],
|
|
14853
|
+
serialize: (v3) => v3.toString(),
|
|
14854
|
+
parse: (v3) => coercePgNumber(v3)
|
|
14855
|
+
}
|
|
14856
|
+
}
|
|
14719
14857
|
});
|
|
14720
14858
|
const db = new PostgresJsDatabase(sql);
|
|
14721
14859
|
return createPostgreSQLAdapterFactory(db);
|
|
@@ -15416,6 +15554,30 @@ var init_dist = __esm(() => {
|
|
|
15416
15554
|
return this.#inner.getReadWriteTransaction();
|
|
15417
15555
|
}
|
|
15418
15556
|
};
|
|
15557
|
+
ArcAuthenticationError = class ArcAuthenticationError extends Error {
|
|
15558
|
+
arcCode = "AUTHENTICATION";
|
|
15559
|
+
constructor(message = "Authentication required") {
|
|
15560
|
+
super(message);
|
|
15561
|
+
this.name = "ArcAuthenticationError";
|
|
15562
|
+
}
|
|
15563
|
+
};
|
|
15564
|
+
ArcAuthorizationError2 = class ArcAuthorizationError2 extends Error {
|
|
15565
|
+
arcCode = "AUTHORIZATION";
|
|
15566
|
+
constructor(message = "Forbidden") {
|
|
15567
|
+
super(message);
|
|
15568
|
+
this.name = "ArcAuthorizationError";
|
|
15569
|
+
}
|
|
15570
|
+
};
|
|
15571
|
+
ArcValidationError2 = class ArcValidationError2 extends Error {
|
|
15572
|
+
arcCode = "VALIDATION";
|
|
15573
|
+
fields;
|
|
15574
|
+
constructor(errors, message = "Invalid parameters") {
|
|
15575
|
+
super(message);
|
|
15576
|
+
this.name = "ArcValidationError";
|
|
15577
|
+
const paths = collectFieldPaths(errors);
|
|
15578
|
+
this.fields = paths.length > 0 ? paths : errors && typeof errors === "object" ? Object.keys(errors) : [];
|
|
15579
|
+
}
|
|
15580
|
+
};
|
|
15419
15581
|
ArcPrimitive = class ArcPrimitive extends ArcAbstract {
|
|
15420
15582
|
serialize(value) {
|
|
15421
15583
|
return value;
|
|
@@ -15577,6 +15739,8 @@ var init_dist = __esm(() => {
|
|
|
15577
15739
|
ArcContextElement = class ArcContextElement extends ArcFragmentBase {
|
|
15578
15740
|
name;
|
|
15579
15741
|
types = ["context-element"];
|
|
15742
|
+
__contextId;
|
|
15743
|
+
__contextName;
|
|
15580
15744
|
get id() {
|
|
15581
15745
|
return this.name;
|
|
15582
15746
|
}
|
|
@@ -15714,7 +15878,8 @@ var init_dist = __esm(() => {
|
|
|
15714
15878
|
payload,
|
|
15715
15879
|
id: this.eventId.generate(),
|
|
15716
15880
|
createdAt: new Date,
|
|
15717
|
-
authContext
|
|
15881
|
+
authContext,
|
|
15882
|
+
definition: this
|
|
15718
15883
|
};
|
|
15719
15884
|
await adapters.eventPublisher.publish(event);
|
|
15720
15885
|
}
|
|
@@ -15767,8 +15932,8 @@ var init_dist = __esm(() => {
|
|
|
15767
15932
|
const tagsSchema = new ArcObject({
|
|
15768
15933
|
_id: new ArcString().primaryKey(),
|
|
15769
15934
|
eventId: new ArcString().index(),
|
|
15770
|
-
tagKey: new ArcString
|
|
15771
|
-
tagValue: new ArcString
|
|
15935
|
+
tagKey: new ArcString,
|
|
15936
|
+
tagValue: new ArcString
|
|
15772
15937
|
});
|
|
15773
15938
|
const syncStatusSchema = new ArcObject({
|
|
15774
15939
|
_id: new ArcString().primaryKey(),
|
|
@@ -15884,6 +16049,8 @@ var init_dist = __esm(() => {
|
|
|
15884
16049
|
if (!this.data.handler) {
|
|
15885
16050
|
throw new Error(`Command "${this.data.name}" has no handler`);
|
|
15886
16051
|
}
|
|
16052
|
+
this.#fn.validateParams(params);
|
|
16053
|
+
await this.#fn.authorize(adapters);
|
|
15887
16054
|
const context2 = this.buildCommandContext(adapters);
|
|
15888
16055
|
return await this.data.handler(context2, params);
|
|
15889
16056
|
}
|
|
@@ -15994,9 +16161,10 @@ var init_dist = __esm(() => {
|
|
|
15994
16161
|
}
|
|
15995
16162
|
}
|
|
15996
16163
|
if (this.data.isAsync) {
|
|
15997
|
-
Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
16164
|
+
const work = Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
15998
16165
|
console.error(`Async listener "${this.data.name}" error:`, error);
|
|
15999
16166
|
});
|
|
16167
|
+
adapters.eventPublisher?.track?.(work);
|
|
16000
16168
|
} else {
|
|
16001
16169
|
await this.data.handler(context2, event2);
|
|
16002
16170
|
}
|
|
@@ -16450,6 +16618,8 @@ var init_dist = __esm(() => {
|
|
|
16450
16618
|
}
|
|
16451
16619
|
};
|
|
16452
16620
|
dateValidator = typeValidatorBuilder("Date", (value) => value instanceof Date);
|
|
16621
|
+
_te = new TextEncoder;
|
|
16622
|
+
_td = new TextDecoder;
|
|
16453
16623
|
originCache = new Map;
|
|
16454
16624
|
originStackCache = new Map;
|
|
16455
16625
|
originError = Symbol("OriginError");
|
|
@@ -16821,6 +16991,8 @@ var init_dist = __esm(() => {
|
|
|
16821
16991
|
}
|
|
16822
16992
|
});
|
|
16823
16993
|
src_default = Postgres;
|
|
16994
|
+
MAX_SAFE_INT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
16995
|
+
MIN_SAFE_INT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
16824
16996
|
PostgreSQLReadWriteTransaction = class PostgreSQLReadWriteTransaction extends PostgreSQLReadTransaction {
|
|
16825
16997
|
adapter;
|
|
16826
16998
|
queries = [];
|
|
@@ -18237,9 +18409,21 @@ class LocalEventPublisher3 {
|
|
|
18237
18409
|
views = [];
|
|
18238
18410
|
syncCallback;
|
|
18239
18411
|
subscribers = new Map;
|
|
18412
|
+
pending = new Set;
|
|
18240
18413
|
constructor(dataStorage) {
|
|
18241
18414
|
this.dataStorage = dataStorage;
|
|
18242
18415
|
}
|
|
18416
|
+
track(work) {
|
|
18417
|
+
const wrapped = Promise.resolve(work).catch(() => {}).finally(() => {
|
|
18418
|
+
this.pending.delete(wrapped);
|
|
18419
|
+
});
|
|
18420
|
+
this.pending.add(wrapped);
|
|
18421
|
+
}
|
|
18422
|
+
async whenIdle() {
|
|
18423
|
+
while (this.pending.size > 0) {
|
|
18424
|
+
await Promise.all([...this.pending]);
|
|
18425
|
+
}
|
|
18426
|
+
}
|
|
18243
18427
|
onPublish(callback) {
|
|
18244
18428
|
this.syncCallback = callback;
|
|
18245
18429
|
}
|
|
@@ -18435,6 +18619,47 @@ class LocalEventPublisher3 {
|
|
|
18435
18619
|
return allViewChanges;
|
|
18436
18620
|
}
|
|
18437
18621
|
}
|
|
18622
|
+
function murmurHash2(key, seed = 0) {
|
|
18623
|
+
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
18624
|
+
remainder = key.length & 3;
|
|
18625
|
+
bytes = key.length - remainder;
|
|
18626
|
+
h1 = seed;
|
|
18627
|
+
c1 = 3432918353;
|
|
18628
|
+
c2 = 461845907;
|
|
18629
|
+
i = 0;
|
|
18630
|
+
while (i < bytes) {
|
|
18631
|
+
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
18632
|
+
++i;
|
|
18633
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
18634
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
18635
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
18636
|
+
h1 ^= k1;
|
|
18637
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
18638
|
+
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
18639
|
+
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
18640
|
+
}
|
|
18641
|
+
k1 = 0;
|
|
18642
|
+
if (remainder >= 3) {
|
|
18643
|
+
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
18644
|
+
}
|
|
18645
|
+
if (remainder >= 2) {
|
|
18646
|
+
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
18647
|
+
}
|
|
18648
|
+
if (remainder >= 1) {
|
|
18649
|
+
k1 ^= key.charCodeAt(i) & 255;
|
|
18650
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
18651
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
18652
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
18653
|
+
h1 ^= k1;
|
|
18654
|
+
}
|
|
18655
|
+
h1 ^= key.length;
|
|
18656
|
+
h1 ^= h1 >>> 16;
|
|
18657
|
+
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
18658
|
+
h1 ^= h1 >>> 13;
|
|
18659
|
+
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
18660
|
+
h1 ^= h1 >>> 16;
|
|
18661
|
+
return h1 >>> 0;
|
|
18662
|
+
}
|
|
18438
18663
|
|
|
18439
18664
|
class ArcOptional2 {
|
|
18440
18665
|
parent;
|
|
@@ -18527,7 +18752,9 @@ class ArcDefault2 {
|
|
|
18527
18752
|
this.defaultValueOrCallback = defaultValueOrCallback;
|
|
18528
18753
|
}
|
|
18529
18754
|
validate(value) {
|
|
18530
|
-
|
|
18755
|
+
if (value === undefined || value === null)
|
|
18756
|
+
return false;
|
|
18757
|
+
return this.parent.validate(value);
|
|
18531
18758
|
}
|
|
18532
18759
|
parse(value) {
|
|
18533
18760
|
if (value)
|
|
@@ -18898,6 +19125,27 @@ class ArcFunction2 {
|
|
|
18898
19125
|
get results() {
|
|
18899
19126
|
return this.data.results;
|
|
18900
19127
|
}
|
|
19128
|
+
validateParams(params) {
|
|
19129
|
+
const schema = this.data.params;
|
|
19130
|
+
if (!schema || typeof schema.validate !== "function")
|
|
19131
|
+
return;
|
|
19132
|
+
const errors = schema.validate(params ?? {});
|
|
19133
|
+
if (errors)
|
|
19134
|
+
throw new ArcValidationError3(errors);
|
|
19135
|
+
}
|
|
19136
|
+
async authorize(adapters) {
|
|
19137
|
+
if (!this.hasProtections)
|
|
19138
|
+
return;
|
|
19139
|
+
const decoded = adapters.authAdapter?.getDecoded?.();
|
|
19140
|
+
if (!decoded) {
|
|
19141
|
+
throw new ArcAuthenticationError2;
|
|
19142
|
+
}
|
|
19143
|
+
const instances = this.data.protections.filter((p3) => p3.token?.name === decoded.tokenName).map((p3) => p3.token.create(decoded.params, adapters));
|
|
19144
|
+
const ok2 = await this.verifyProtections(instances);
|
|
19145
|
+
if (!ok2) {
|
|
19146
|
+
throw new ArcAuthorizationError3;
|
|
19147
|
+
}
|
|
19148
|
+
}
|
|
18901
19149
|
async verifyProtections(tokens) {
|
|
18902
19150
|
if (!this.data.protections || this.data.protections.length === 0) {
|
|
18903
19151
|
return true;
|
|
@@ -19049,47 +19297,6 @@ function deepMerge2(target, source) {
|
|
|
19049
19297
|
function isPlainObject2(item) {
|
|
19050
19298
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
19051
19299
|
}
|
|
19052
|
-
function murmurHash2(key, seed = 0) {
|
|
19053
|
-
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
19054
|
-
remainder = key.length & 3;
|
|
19055
|
-
bytes = key.length - remainder;
|
|
19056
|
-
h1 = seed;
|
|
19057
|
-
c1 = 3432918353;
|
|
19058
|
-
c2 = 461845907;
|
|
19059
|
-
i = 0;
|
|
19060
|
-
while (i < bytes) {
|
|
19061
|
-
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
19062
|
-
++i;
|
|
19063
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
19064
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
19065
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
19066
|
-
h1 ^= k1;
|
|
19067
|
-
h1 = h1 << 13 | h1 >>> 19;
|
|
19068
|
-
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
19069
|
-
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
19070
|
-
}
|
|
19071
|
-
k1 = 0;
|
|
19072
|
-
if (remainder >= 3) {
|
|
19073
|
-
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
19074
|
-
}
|
|
19075
|
-
if (remainder >= 2) {
|
|
19076
|
-
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
19077
|
-
}
|
|
19078
|
-
if (remainder >= 1) {
|
|
19079
|
-
k1 ^= key.charCodeAt(i) & 255;
|
|
19080
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
19081
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
19082
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
19083
|
-
h1 ^= k1;
|
|
19084
|
-
}
|
|
19085
|
-
h1 ^= key.length;
|
|
19086
|
-
h1 ^= h1 >>> 16;
|
|
19087
|
-
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
19088
|
-
h1 ^= h1 >>> 13;
|
|
19089
|
-
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
19090
|
-
h1 ^= h1 >>> 16;
|
|
19091
|
-
return h1 >>> 0;
|
|
19092
|
-
}
|
|
19093
19300
|
function resolveQueryChange2(currentResult, event3, options) {
|
|
19094
19301
|
const index = currentResult.findIndex((e2) => e2._id === event3.id);
|
|
19095
19302
|
const isInCurrentResult = index !== -1;
|
|
@@ -19102,12 +19309,12 @@ function resolveQueryChange2(currentResult, event3, options) {
|
|
|
19102
19309
|
const shouldBeInResult = checkItemMatchesWhere2(event3.item, options.where);
|
|
19103
19310
|
if (isInCurrentResult && shouldBeInResult) {
|
|
19104
19311
|
const newResult = currentResult.toSpliced(index, 1, event3.item);
|
|
19105
|
-
return
|
|
19312
|
+
return applyOrderByAndLimit(newResult, options);
|
|
19106
19313
|
} else if (isInCurrentResult && !shouldBeInResult) {
|
|
19107
19314
|
return currentResult.toSpliced(index, 1);
|
|
19108
19315
|
} else if (!isInCurrentResult && shouldBeInResult) {
|
|
19109
19316
|
const newResult = [...currentResult, event3.item];
|
|
19110
|
-
return
|
|
19317
|
+
return applyOrderByAndLimit(newResult, options);
|
|
19111
19318
|
}
|
|
19112
19319
|
return false;
|
|
19113
19320
|
}
|
|
@@ -19146,7 +19353,7 @@ function checkItemMatchesWhere2(item, where) {
|
|
|
19146
19353
|
});
|
|
19147
19354
|
});
|
|
19148
19355
|
}
|
|
19149
|
-
function
|
|
19356
|
+
function applyOrderByAndLimit(result, options) {
|
|
19150
19357
|
let sorted = result;
|
|
19151
19358
|
if (options.orderBy) {
|
|
19152
19359
|
sorted = [...result].sort((a2, b4) => {
|
|
@@ -19502,7 +19709,7 @@ class Model3 {
|
|
|
19502
19709
|
return s;
|
|
19503
19710
|
}
|
|
19504
19711
|
}
|
|
19505
|
-
function
|
|
19712
|
+
function applyQueryChanges3(result, changes) {
|
|
19506
19713
|
const next = [...result];
|
|
19507
19714
|
for (const change of changes) {
|
|
19508
19715
|
if (change.type === "delete") {
|
|
@@ -19555,7 +19762,7 @@ class StreamingQueryCache2 {
|
|
|
19555
19762
|
if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
|
|
19556
19763
|
return;
|
|
19557
19764
|
}
|
|
19558
|
-
newEntry.result =
|
|
19765
|
+
newEntry.result = applyQueryChanges3(newEntry.result, changes);
|
|
19559
19766
|
this.notify(newEntry);
|
|
19560
19767
|
}
|
|
19561
19768
|
});
|
|
@@ -20514,7 +20721,7 @@ var Operation2, PROXY_DRAFT2, RAW_RETURN_SYMBOL2, iteratorSymbol2, dataTypes2, i
|
|
|
20514
20721
|
}
|
|
20515
20722
|
return returnValue(result);
|
|
20516
20723
|
};
|
|
20517
|
-
}, create2, constructorString2, TOKEN_PREFIX2 = "arc:token:", DEFAULT_TIMEOUT_MS2 = 8000, provider2 = null, latestSync2 = null, syncSeq2 = 0, eventWireInstanceCounter2 = 0, EVENT_TABLES2, arrayValidator2, ArcArray2, objectValidator2, ArcObject2, ScopedDataStorage2, ArcPrimitive2, stringValidator2, ArcString2, ArcContextElement2, ArcBoolean2, ArcId2, numberValidator2, ArcNumber2, ArcEvent2, ArcCommand2, ArcListener2, ArcRoute2, ForkedStoreState2, ForkedDataStorage2, MasterStoreState2, MasterDataStorage3, dateValidator2, SQLiteReadWriteTransaction, createSQLiteAdapterFactory = (db) => {
|
|
20724
|
+
}, create2, constructorString2, TOKEN_PREFIX2 = "arc:token:", DEFAULT_TIMEOUT_MS2 = 8000, provider2 = null, latestSync2 = null, syncSeq2 = 0, eventWireInstanceCounter2 = 0, EVENT_TABLES2, arrayValidator2, ArcArray2, objectValidator2, ArcObject2, ScopedDataStorage2, ArcAuthenticationError2, ArcAuthorizationError3, ArcValidationError3, ArcPrimitive2, stringValidator2, ArcString2, ArcContextElement2, ArcBoolean2, ArcId2, numberValidator2, ArcNumber2, ArcEvent2, ArcCommand2, ArcListener2, ArcRoute2, ForkedStoreState2, ForkedDataStorage2, MasterStoreState2, MasterDataStorage3, dateValidator2, _te2, _td2, SQLiteReadWriteTransaction, createSQLiteAdapterFactory = (db) => {
|
|
20518
20725
|
return async (context) => {
|
|
20519
20726
|
const adapter = new SQLiteAdapter(db, context);
|
|
20520
20727
|
await adapter.initialize();
|
|
@@ -21222,6 +21429,29 @@ var init_dist2 = __esm(() => {
|
|
|
21222
21429
|
return this.#inner.getReadWriteTransaction();
|
|
21223
21430
|
}
|
|
21224
21431
|
};
|
|
21432
|
+
ArcAuthenticationError2 = class ArcAuthenticationError2 extends Error {
|
|
21433
|
+
arcCode = "AUTHENTICATION";
|
|
21434
|
+
constructor(message = "Authentication required") {
|
|
21435
|
+
super(message);
|
|
21436
|
+
this.name = "ArcAuthenticationError";
|
|
21437
|
+
}
|
|
21438
|
+
};
|
|
21439
|
+
ArcAuthorizationError3 = class ArcAuthorizationError3 extends Error {
|
|
21440
|
+
arcCode = "AUTHORIZATION";
|
|
21441
|
+
constructor(message = "Forbidden") {
|
|
21442
|
+
super(message);
|
|
21443
|
+
this.name = "ArcAuthorizationError";
|
|
21444
|
+
}
|
|
21445
|
+
};
|
|
21446
|
+
ArcValidationError3 = class ArcValidationError3 extends Error {
|
|
21447
|
+
arcCode = "VALIDATION";
|
|
21448
|
+
fields;
|
|
21449
|
+
constructor(errors, message = "Invalid parameters") {
|
|
21450
|
+
super(message);
|
|
21451
|
+
this.name = "ArcValidationError";
|
|
21452
|
+
this.fields = errors && typeof errors === "object" ? Object.keys(errors) : [];
|
|
21453
|
+
}
|
|
21454
|
+
};
|
|
21225
21455
|
ArcPrimitive2 = class ArcPrimitive2 extends ArcAbstract2 {
|
|
21226
21456
|
serialize(value) {
|
|
21227
21457
|
return value;
|
|
@@ -21383,6 +21613,8 @@ var init_dist2 = __esm(() => {
|
|
|
21383
21613
|
ArcContextElement2 = class ArcContextElement2 extends ArcFragmentBase2 {
|
|
21384
21614
|
name;
|
|
21385
21615
|
types = ["context-element"];
|
|
21616
|
+
__contextId;
|
|
21617
|
+
__contextName;
|
|
21386
21618
|
get id() {
|
|
21387
21619
|
return this.name;
|
|
21388
21620
|
}
|
|
@@ -21690,6 +21922,8 @@ var init_dist2 = __esm(() => {
|
|
|
21690
21922
|
if (!this.data.handler) {
|
|
21691
21923
|
throw new Error(`Command "${this.data.name}" has no handler`);
|
|
21692
21924
|
}
|
|
21925
|
+
this.#fn.validateParams(params);
|
|
21926
|
+
await this.#fn.authorize(adapters);
|
|
21693
21927
|
const context2 = this.buildCommandContext(adapters);
|
|
21694
21928
|
return await this.data.handler(context2, params);
|
|
21695
21929
|
}
|
|
@@ -21800,9 +22034,10 @@ var init_dist2 = __esm(() => {
|
|
|
21800
22034
|
}
|
|
21801
22035
|
}
|
|
21802
22036
|
if (this.data.isAsync) {
|
|
21803
|
-
Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
22037
|
+
const work = Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
21804
22038
|
console.error(`Async listener "${this.data.name}" error:`, error);
|
|
21805
22039
|
});
|
|
22040
|
+
adapters.eventPublisher?.track?.(work);
|
|
21806
22041
|
} else {
|
|
21807
22042
|
await this.data.handler(context2, event2);
|
|
21808
22043
|
}
|
|
@@ -22256,6 +22491,8 @@ var init_dist2 = __esm(() => {
|
|
|
22256
22491
|
}
|
|
22257
22492
|
};
|
|
22258
22493
|
dateValidator2 = typeValidatorBuilder2("Date", (value) => value instanceof Date);
|
|
22494
|
+
_te2 = new TextEncoder;
|
|
22495
|
+
_td2 = new TextDecoder;
|
|
22259
22496
|
SQLiteReadWriteTransaction = class SQLiteReadWriteTransaction extends SQLiteReadTransaction {
|
|
22260
22497
|
adapter;
|
|
22261
22498
|
queries = [];
|
|
@@ -36687,7 +36924,8 @@ class ContextHandler {
|
|
|
36687
36924
|
type: event.type,
|
|
36688
36925
|
payload: event.payload,
|
|
36689
36926
|
createdAt: new Date(event.createdAt),
|
|
36690
|
-
authContext: eventAuthContext
|
|
36927
|
+
authContext: eventAuthContext,
|
|
36928
|
+
definition: eventDef
|
|
36691
36929
|
});
|
|
36692
36930
|
persistedEvents.push(syncableEvent);
|
|
36693
36931
|
}
|
|
@@ -37464,14 +37702,34 @@ function arcHttpHandlers(ch, cm) {
|
|
|
37464
37702
|
];
|
|
37465
37703
|
}
|
|
37466
37704
|
// ../host/src/middleware/ws.ts
|
|
37467
|
-
import { LiveQuery } from "@arcote.tech/arc";
|
|
37468
|
-
var
|
|
37469
|
-
|
|
37470
|
-
|
|
37705
|
+
import { applyQueryChanges, LiveQuery } from "@arcote.tech/arc";
|
|
37706
|
+
var sharedQueries = new Map;
|
|
37707
|
+
var clientSubKeys = new Map;
|
|
37708
|
+
function sharedKeyFor(descriptor, scope, rawToken) {
|
|
37709
|
+
return JSON.stringify([scope, rawToken, descriptor]);
|
|
37710
|
+
}
|
|
37711
|
+
function detachSub(clientId, subscriptionId, sharedKey) {
|
|
37712
|
+
const entry = sharedQueries.get(sharedKey);
|
|
37713
|
+
if (!entry)
|
|
37714
|
+
return;
|
|
37715
|
+
const subs = entry.subscribers.get(clientId);
|
|
37471
37716
|
if (subs) {
|
|
37472
|
-
|
|
37473
|
-
|
|
37474
|
-
|
|
37717
|
+
subs.delete(subscriptionId);
|
|
37718
|
+
if (subs.size === 0)
|
|
37719
|
+
entry.subscribers.delete(clientId);
|
|
37720
|
+
}
|
|
37721
|
+
if (entry.subscribers.size === 0) {
|
|
37722
|
+
entry.live.stop();
|
|
37723
|
+
sharedQueries.delete(sharedKey);
|
|
37724
|
+
}
|
|
37725
|
+
}
|
|
37726
|
+
function cleanupClientSubs(clientId) {
|
|
37727
|
+
const keys = clientSubKeys.get(clientId);
|
|
37728
|
+
if (keys) {
|
|
37729
|
+
for (const [subscriptionId, sharedKey] of keys) {
|
|
37730
|
+
detachSub(clientId, subscriptionId, sharedKey);
|
|
37731
|
+
}
|
|
37732
|
+
clientSubKeys.delete(clientId);
|
|
37475
37733
|
}
|
|
37476
37734
|
}
|
|
37477
37735
|
function scopeAuthHandler() {
|
|
@@ -37580,37 +37838,90 @@ function querySubscriptionHandler() {
|
|
|
37580
37838
|
if (!rawToken && client.scopeTokens.size > 0) {
|
|
37581
37839
|
rawToken = client.scopeTokens.values().next().value.raw;
|
|
37582
37840
|
}
|
|
37583
|
-
|
|
37584
|
-
|
|
37585
|
-
|
|
37586
|
-
|
|
37587
|
-
|
|
37588
|
-
|
|
37589
|
-
|
|
37590
|
-
});
|
|
37591
|
-
} else {
|
|
37592
|
-
ctx.connectionManager.sendToClient(client.id, {
|
|
37593
|
-
type: "query-snapshot",
|
|
37594
|
-
subscriptionId,
|
|
37595
|
-
result: update.result ?? null
|
|
37596
|
-
});
|
|
37841
|
+
const prevKey = clientSubKeys.get(client.id)?.get(subscriptionId);
|
|
37842
|
+
if (prevKey)
|
|
37843
|
+
detachSub(client.id, subscriptionId, prevKey);
|
|
37844
|
+
const sharedKey = sharedKeyFor(descriptor, scope, rawToken);
|
|
37845
|
+
const attach = (entry2) => {
|
|
37846
|
+
if (!entry2.subscribers.has(client.id)) {
|
|
37847
|
+
entry2.subscribers.set(client.id, new Set);
|
|
37597
37848
|
}
|
|
37598
|
-
|
|
37599
|
-
|
|
37600
|
-
|
|
37601
|
-
|
|
37602
|
-
|
|
37603
|
-
|
|
37604
|
-
|
|
37849
|
+
entry2.subscribers.get(client.id).add(subscriptionId);
|
|
37850
|
+
if (!clientSubKeys.has(client.id)) {
|
|
37851
|
+
clientSubKeys.set(client.id, new Map);
|
|
37852
|
+
}
|
|
37853
|
+
clientSubKeys.get(client.id).set(subscriptionId, sharedKey);
|
|
37854
|
+
};
|
|
37855
|
+
const existing = sharedQueries.get(sharedKey);
|
|
37856
|
+
if (existing && existing.ready) {
|
|
37857
|
+
attach(existing);
|
|
37605
37858
|
ctx.connectionManager.sendToClient(client.id, {
|
|
37606
37859
|
type: "query-snapshot",
|
|
37607
37860
|
subscriptionId,
|
|
37608
|
-
result:
|
|
37861
|
+
result: existing.lastResult ?? null
|
|
37609
37862
|
});
|
|
37610
|
-
|
|
37863
|
+
return true;
|
|
37864
|
+
}
|
|
37865
|
+
if (existing) {
|
|
37866
|
+
attach(existing);
|
|
37867
|
+
return true;
|
|
37868
|
+
}
|
|
37869
|
+
const entry = {
|
|
37870
|
+
live: null,
|
|
37871
|
+
subscribers: new Map,
|
|
37872
|
+
lastResult: null,
|
|
37873
|
+
ready: false
|
|
37874
|
+
};
|
|
37875
|
+
entry.live = new LiveQuery(ctx.contextHandler.getModel(), descriptor, scope, rawToken, (update) => {
|
|
37876
|
+
if (update.type === "changes") {
|
|
37877
|
+
if (Array.isArray(entry.lastResult)) {
|
|
37878
|
+
entry.lastResult = applyQueryChanges(entry.lastResult, update.changes);
|
|
37879
|
+
}
|
|
37880
|
+
} else {
|
|
37881
|
+
entry.lastResult = update.result ?? null;
|
|
37882
|
+
}
|
|
37883
|
+
for (const [subClientId, subIds] of entry.subscribers) {
|
|
37884
|
+
for (const subId of subIds) {
|
|
37885
|
+
ctx.connectionManager.sendToClient(subClientId, update.type === "changes" ? {
|
|
37886
|
+
type: "query-changes",
|
|
37887
|
+
subscriptionId: subId,
|
|
37888
|
+
changes: update.changes
|
|
37889
|
+
} : {
|
|
37890
|
+
type: "query-snapshot",
|
|
37891
|
+
subscriptionId: subId,
|
|
37892
|
+
result: update.result ?? null
|
|
37893
|
+
});
|
|
37894
|
+
}
|
|
37895
|
+
}
|
|
37896
|
+
});
|
|
37897
|
+
sharedQueries.set(sharedKey, entry);
|
|
37898
|
+
attach(entry);
|
|
37899
|
+
try {
|
|
37900
|
+
const result = await entry.live.start();
|
|
37901
|
+
entry.lastResult = result ?? null;
|
|
37902
|
+
entry.ready = true;
|
|
37903
|
+
for (const [subClientId, subIds] of entry.subscribers) {
|
|
37904
|
+
for (const subId of subIds) {
|
|
37905
|
+
ctx.connectionManager.sendToClient(subClientId, {
|
|
37906
|
+
type: "query-snapshot",
|
|
37907
|
+
subscriptionId: subId,
|
|
37908
|
+
result: result ?? null
|
|
37909
|
+
});
|
|
37910
|
+
}
|
|
37911
|
+
}
|
|
37912
|
+
entry.live.flush();
|
|
37611
37913
|
} catch (err3) {
|
|
37612
|
-
live.stop();
|
|
37613
|
-
|
|
37914
|
+
entry.live.stop();
|
|
37915
|
+
sharedQueries.delete(sharedKey);
|
|
37916
|
+
for (const subClientId of entry.subscribers.keys()) {
|
|
37917
|
+
const keys = clientSubKeys.get(subClientId);
|
|
37918
|
+
if (keys) {
|
|
37919
|
+
for (const [subId, key] of keys) {
|
|
37920
|
+
if (key === sharedKey)
|
|
37921
|
+
keys.delete(subId);
|
|
37922
|
+
}
|
|
37923
|
+
}
|
|
37924
|
+
}
|
|
37614
37925
|
console.error(`[Arc] Query subscription error (${descriptor?.element}.${descriptor?.method}):`, err3);
|
|
37615
37926
|
ctx.connectionManager.sendToClient(client.id, {
|
|
37616
37927
|
type: "error",
|
|
@@ -37620,11 +37931,10 @@ function querySubscriptionHandler() {
|
|
|
37620
37931
|
return true;
|
|
37621
37932
|
}
|
|
37622
37933
|
if (message.type === "unsubscribe-query") {
|
|
37623
|
-
const
|
|
37624
|
-
|
|
37625
|
-
|
|
37626
|
-
|
|
37627
|
-
subs.delete(message.subscriptionId);
|
|
37934
|
+
const key = clientSubKeys.get(client.id)?.get(message.subscriptionId);
|
|
37935
|
+
if (key) {
|
|
37936
|
+
detachSub(client.id, message.subscriptionId, key);
|
|
37937
|
+
clientSubKeys.get(client.id)?.delete(message.subscriptionId);
|
|
37628
37938
|
}
|
|
37629
37939
|
return true;
|
|
37630
37940
|
}
|
|
@@ -37826,7 +38136,7 @@ async function createArcServer(config) {
|
|
|
37826
38136
|
cronScheduler,
|
|
37827
38137
|
stop: () => {
|
|
37828
38138
|
cronScheduler.stop();
|
|
37829
|
-
server.stop();
|
|
38139
|
+
server.stop(true);
|
|
37830
38140
|
}
|
|
37831
38141
|
};
|
|
37832
38142
|
}
|
|
@@ -37865,10 +38175,10 @@ function generateShellHtml(appName, manifest, initial, stylesHash) {
|
|
|
37865
38175
|
<html lang="en">
|
|
37866
38176
|
<head>
|
|
37867
38177
|
<meta charset="UTF-8" />
|
|
37868
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
38178
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
|
37869
38179
|
<title>${manifest?.title ?? appName}</title>${manifest?.favicon ? `
|
|
37870
38180
|
<link rel="icon" href="${manifest.favicon}">` : ""}${manifest ? `
|
|
37871
|
-
<link rel="manifest" href="/manifest.json">` : ""}
|
|
38181
|
+
<link rel="manifest" href="/manifest.json${stylesQs}">` : ""}
|
|
37872
38182
|
<link rel="stylesheet" href="/styles.css${stylesQs}" />
|
|
37873
38183
|
<link rel="stylesheet" href="/theme.css${stylesQs}" />
|
|
37874
38184
|
<link rel="modulepreload" href="${initialUrl}" />${otelTag}
|
|
@@ -38046,7 +38356,10 @@ function staticFilesHandler(ws, devMode, getManifest) {
|
|
|
38046
38356
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
38047
38357
|
});
|
|
38048
38358
|
if ((path4 === "/manifest.json" || path4 === "/manifest.webmanifest") && ws.manifest) {
|
|
38049
|
-
return serveFile(ws.manifest.path,
|
|
38359
|
+
return serveFile(ws.manifest.path, {
|
|
38360
|
+
...ctx.corsHeaders,
|
|
38361
|
+
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
38362
|
+
});
|
|
38050
38363
|
}
|
|
38051
38364
|
if (path4.lastIndexOf(".") > path4.lastIndexOf("/")) {
|
|
38052
38365
|
const publicFile = join21(ws.publicDir, path4.slice(1));
|
|
@@ -38064,7 +38377,12 @@ function apiEndpointsHandler(ws, getManifest, cm, moduleAccessMap, telemetry) {
|
|
|
38064
38377
|
if (payloads.length === 0 && ctx.tokenPayload) {
|
|
38065
38378
|
payloads = [ctx.tokenPayload];
|
|
38066
38379
|
}
|
|
38067
|
-
return filterManifestForTokens(getManifest(), moduleAccessMap, payloads).then((filtered) => Response.json(filtered, {
|
|
38380
|
+
return filterManifestForTokens(getManifest(), moduleAccessMap, payloads).then((filtered) => Response.json(filtered, {
|
|
38381
|
+
headers: {
|
|
38382
|
+
...ctx.corsHeaders,
|
|
38383
|
+
"Cache-Control": "no-cache, private"
|
|
38384
|
+
}
|
|
38385
|
+
}));
|
|
38068
38386
|
}
|
|
38069
38387
|
if (url.pathname === "/api/translations") {
|
|
38070
38388
|
const config = readTranslationsConfig(ws.rootDir);
|
|
@@ -38114,7 +38432,11 @@ function devReloadHandler(sseClients) {
|
|
|
38114
38432
|
function spaFallbackHandler(getShellHtml) {
|
|
38115
38433
|
return (_req, _url, ctx) => {
|
|
38116
38434
|
return new Response(getShellHtml(), {
|
|
38117
|
-
headers: {
|
|
38435
|
+
headers: {
|
|
38436
|
+
...ctx.corsHeaders,
|
|
38437
|
+
"Content-Type": "text/html",
|
|
38438
|
+
"Cache-Control": "no-cache, must-revalidate"
|
|
38439
|
+
}
|
|
38118
38440
|
});
|
|
38119
38441
|
};
|
|
38120
38442
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc-cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.28",
|
|
4
4
|
"description": "CLI tool for Arc framework",
|
|
5
5
|
"module": "index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"build": "bun build --target=bun ./src/index.ts --outdir=dist --external @arcote.tech/arc --external @arcote.tech/arc-ds --external @arcote.tech/arc-react --external @arcote.tech/platform --external @arcote.tech/arc-map --external '@opentelemetry/*' && chmod +x dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@arcote.tech/arc": "^0.7.
|
|
16
|
-
"@arcote.tech/arc-ds": "^0.7.
|
|
17
|
-
"@arcote.tech/arc-react": "^0.7.
|
|
18
|
-
"@arcote.tech/arc-host": "^0.7.
|
|
19
|
-
"@arcote.tech/arc-adapter-db-sqlite": "^0.7.
|
|
20
|
-
"@arcote.tech/arc-adapter-db-postgres": "^0.7.
|
|
21
|
-
"@arcote.tech/arc-otel": "^0.7.
|
|
15
|
+
"@arcote.tech/arc": "^0.7.28",
|
|
16
|
+
"@arcote.tech/arc-ds": "^0.7.28",
|
|
17
|
+
"@arcote.tech/arc-react": "^0.7.28",
|
|
18
|
+
"@arcote.tech/arc-host": "^0.7.28",
|
|
19
|
+
"@arcote.tech/arc-adapter-db-sqlite": "^0.7.28",
|
|
20
|
+
"@arcote.tech/arc-adapter-db-postgres": "^0.7.28",
|
|
21
|
+
"@arcote.tech/arc-otel": "^0.7.28",
|
|
22
22
|
"@opentelemetry/api": "^1.9.0",
|
|
23
23
|
"@opentelemetry/api-logs": "^0.57.0",
|
|
24
24
|
"@opentelemetry/core": "^1.30.0",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|
|
32
32
|
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
33
33
|
"@opentelemetry/semantic-conventions": "^1.27.0",
|
|
34
|
-
"@arcote.tech/platform": "^0.7.
|
|
35
|
-
"@arcote.tech/arc-map": "^0.7.
|
|
34
|
+
"@arcote.tech/platform": "^0.7.28",
|
|
35
|
+
"@arcote.tech/arc-map": "^0.7.28",
|
|
36
36
|
"@clack/prompts": "^0.9.0",
|
|
37
37
|
"commander": "^11.1.0",
|
|
38
38
|
"chokidar": "^3.5.3",
|
package/src/platform/server.ts
CHANGED
|
@@ -134,8 +134,8 @@ export function generateShellHtml(
|
|
|
134
134
|
<html lang="en">
|
|
135
135
|
<head>
|
|
136
136
|
<meta charset="UTF-8" />
|
|
137
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
138
|
-
<title>${manifest?.title ?? appName}</title>${manifest?.favicon ? `\n <link rel="icon" href="${manifest.favicon}">` : ""}${manifest ? `\n <link rel="manifest" href="/manifest.json">` : ""}
|
|
137
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
|
138
|
+
<title>${manifest?.title ?? appName}</title>${manifest?.favicon ? `\n <link rel="icon" href="${manifest.favicon}">` : ""}${manifest ? `\n <link rel="manifest" href="/manifest.json${stylesQs}">` : ""}
|
|
139
139
|
<link rel="stylesheet" href="/styles.css${stylesQs}" />
|
|
140
140
|
<link rel="stylesheet" href="/theme.css${stylesQs}" />
|
|
141
141
|
<link rel="modulepreload" href="${initialUrl}" />${otelTag}
|
|
@@ -403,9 +403,15 @@ function staticFilesHandler(
|
|
|
403
403
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable",
|
|
404
404
|
});
|
|
405
405
|
|
|
406
|
-
// Serve manifest.json from root dir
|
|
406
|
+
// Serve manifest.json from root dir. Stable URL, content changes between
|
|
407
|
+
// builds — HTML references it with `?v=<stylesHash>` (generateShellHtml),
|
|
408
|
+
// so the URL changes on rebuild and immutable caching is safe. Handler
|
|
409
|
+
// ignores the query string itself (same pattern as /styles.css).
|
|
407
410
|
if ((path === "/manifest.json" || path === "/manifest.webmanifest") && ws.manifest) {
|
|
408
|
-
return serveFile(ws.manifest.path,
|
|
411
|
+
return serveFile(ws.manifest.path, {
|
|
412
|
+
...ctx.corsHeaders,
|
|
413
|
+
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable",
|
|
414
|
+
});
|
|
409
415
|
}
|
|
410
416
|
|
|
411
417
|
// Public files (files with extensions)
|
|
@@ -436,7 +442,18 @@ function apiEndpointsHandler(
|
|
|
436
442
|
payloads = [ctx.tokenPayload];
|
|
437
443
|
}
|
|
438
444
|
return filterManifestForTokens(getManifest(), moduleAccessMap, payloads)
|
|
439
|
-
.then((filtered) =>
|
|
445
|
+
.then((filtered) =>
|
|
446
|
+
Response.json(filtered, {
|
|
447
|
+
headers: {
|
|
448
|
+
...ctx.corsHeaders,
|
|
449
|
+
// Treść zależy od tokenu (filterManifestForTokens) i zmienia się
|
|
450
|
+
// co deploy. Nie jest artefaktem buildu — `private`, by pośredni
|
|
451
|
+
// cache nie podał manifestu jednego usera drugiemu, `no-cache`,
|
|
452
|
+
// by po deployu klient dostał świeże hashe/podpisy chunków.
|
|
453
|
+
"Cache-Control": "no-cache, private",
|
|
454
|
+
},
|
|
455
|
+
}),
|
|
456
|
+
);
|
|
440
457
|
}
|
|
441
458
|
|
|
442
459
|
if (url.pathname === "/api/translations") {
|
|
@@ -501,7 +518,15 @@ function devReloadHandler(
|
|
|
501
518
|
function spaFallbackHandler(getShellHtml: () => string): ArcHttpHandler {
|
|
502
519
|
return (_req, _url, ctx) => {
|
|
503
520
|
return new Response(getShellHtml(), {
|
|
504
|
-
headers: {
|
|
521
|
+
headers: {
|
|
522
|
+
...ctx.corsHeaders,
|
|
523
|
+
"Content-Type": "text/html",
|
|
524
|
+
// Stabilny URL, zmienna treść (embeduje initial.<hash>.js + styles ?v=).
|
|
525
|
+
// Kotwica całego łańcucha — musi być zawsze rewalidowana, inaczej po
|
|
526
|
+
// deployu przeglądarka/CDN podaje stary shell wskazujący na nieistniejące
|
|
527
|
+
// już bundle. Hash nie pomoże: to URL trasy, którego nie da się zahashować.
|
|
528
|
+
"Cache-Control": "no-cache, must-revalidate",
|
|
529
|
+
},
|
|
505
530
|
});
|
|
506
531
|
};
|
|
507
532
|
}
|