@arcote.tech/arc-cli 0.7.16 → 0.7.17
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 +572 -711
- package/package.json +9 -9
- package/src/builder/chunk-planner.ts +92 -8
- package/src/platform/server.ts +14 -11
- package/src/platform/shared.ts +5 -1
package/dist/index.js
CHANGED
|
@@ -14017,7 +14017,8 @@ class EventWire {
|
|
|
14017
14017
|
onSyncedCallback;
|
|
14018
14018
|
reconnectTimeout;
|
|
14019
14019
|
syncRequested = false;
|
|
14020
|
-
|
|
14020
|
+
querySubscriptions = new Map;
|
|
14021
|
+
querySubCounter = 0;
|
|
14021
14022
|
enableEventSync;
|
|
14022
14023
|
constructor(baseUrl, options) {
|
|
14023
14024
|
this.baseUrl = baseUrl;
|
|
@@ -14072,7 +14073,7 @@ class EventWire {
|
|
|
14072
14073
|
this.requestSync();
|
|
14073
14074
|
}
|
|
14074
14075
|
this.flushPendingEvents();
|
|
14075
|
-
this.
|
|
14076
|
+
this.sendAllQuerySubscriptions();
|
|
14076
14077
|
} else {
|
|
14077
14078
|
console.log(`[EventWire] onopen called but ws is not OPEN, readyState:`, this.ws?.readyState);
|
|
14078
14079
|
}
|
|
@@ -14148,24 +14149,29 @@ class EventWire {
|
|
|
14148
14149
|
onSynced(callback) {
|
|
14149
14150
|
this.onSyncedCallback = callback;
|
|
14150
14151
|
}
|
|
14151
|
-
|
|
14152
|
-
const
|
|
14153
|
-
this.
|
|
14152
|
+
subscribeQuery(descriptor, scope, callbacks) {
|
|
14153
|
+
const subscriptionId = `qs_${this.instanceId}_${++this.querySubCounter}`;
|
|
14154
|
+
this.querySubscriptions.set(subscriptionId, {
|
|
14155
|
+
descriptor,
|
|
14156
|
+
scope,
|
|
14157
|
+
callbacks
|
|
14158
|
+
});
|
|
14154
14159
|
if (this.state === "connected" && this.ws) {
|
|
14155
14160
|
this.ws.send(JSON.stringify({
|
|
14156
|
-
type: "subscribe-
|
|
14157
|
-
|
|
14161
|
+
type: "subscribe-query",
|
|
14162
|
+
subscriptionId,
|
|
14163
|
+
descriptor,
|
|
14158
14164
|
scope
|
|
14159
14165
|
}));
|
|
14160
14166
|
}
|
|
14167
|
+
return subscriptionId;
|
|
14161
14168
|
}
|
|
14162
|
-
|
|
14163
|
-
this.
|
|
14169
|
+
unsubscribeQuery(subscriptionId) {
|
|
14170
|
+
this.querySubscriptions.delete(subscriptionId);
|
|
14164
14171
|
if (this.state === "connected" && this.ws) {
|
|
14165
14172
|
this.ws.send(JSON.stringify({
|
|
14166
|
-
type: "unsubscribe-
|
|
14167
|
-
|
|
14168
|
-
scope
|
|
14173
|
+
type: "unsubscribe-query",
|
|
14174
|
+
subscriptionId
|
|
14169
14175
|
}));
|
|
14170
14176
|
}
|
|
14171
14177
|
}
|
|
@@ -14200,17 +14206,17 @@ class EventWire {
|
|
|
14200
14206
|
this.lastHostEventId = message.lastHostEventId;
|
|
14201
14207
|
}
|
|
14202
14208
|
break;
|
|
14203
|
-
case "
|
|
14204
|
-
const sub = this.
|
|
14209
|
+
case "query-snapshot": {
|
|
14210
|
+
const sub = this.querySubscriptions.get(message.subscriptionId);
|
|
14205
14211
|
if (sub) {
|
|
14206
|
-
sub.onSnapshot(message.
|
|
14212
|
+
sub.callbacks.onSnapshot(message.result ?? null);
|
|
14207
14213
|
}
|
|
14208
14214
|
break;
|
|
14209
14215
|
}
|
|
14210
|
-
case "
|
|
14211
|
-
const sub = this.
|
|
14216
|
+
case "query-changes": {
|
|
14217
|
+
const sub = this.querySubscriptions.get(message.subscriptionId);
|
|
14212
14218
|
if (sub && Array.isArray(message.changes)) {
|
|
14213
|
-
sub.onChanges(message.changes);
|
|
14219
|
+
sub.callbacks.onChanges(message.changes);
|
|
14214
14220
|
}
|
|
14215
14221
|
break;
|
|
14216
14222
|
}
|
|
@@ -14238,17 +14244,15 @@ class EventWire {
|
|
|
14238
14244
|
this.pendingEvents = [];
|
|
14239
14245
|
}
|
|
14240
14246
|
}
|
|
14241
|
-
|
|
14247
|
+
sendAllQuerySubscriptions() {
|
|
14242
14248
|
if (!this.ws || this.state !== "connected")
|
|
14243
14249
|
return;
|
|
14244
|
-
for (const
|
|
14245
|
-
const sepIdx = key.indexOf(":");
|
|
14246
|
-
const scope = key.slice(0, sepIdx);
|
|
14247
|
-
const element = key.slice(sepIdx + 1);
|
|
14250
|
+
for (const [subscriptionId, sub] of this.querySubscriptions) {
|
|
14248
14251
|
this.ws.send(JSON.stringify({
|
|
14249
|
-
type: "subscribe-
|
|
14250
|
-
|
|
14251
|
-
|
|
14252
|
+
type: "subscribe-query",
|
|
14253
|
+
subscriptionId,
|
|
14254
|
+
descriptor: sub.descriptor,
|
|
14255
|
+
scope: sub.scope
|
|
14252
14256
|
}));
|
|
14253
14257
|
}
|
|
14254
14258
|
}
|
|
@@ -14267,19 +14271,12 @@ class LocalEventPublisher2 {
|
|
|
14267
14271
|
views = [];
|
|
14268
14272
|
syncCallback;
|
|
14269
14273
|
subscribers = new Map;
|
|
14270
|
-
viewChangesCallbacks = new Set;
|
|
14271
14274
|
constructor(dataStorage) {
|
|
14272
14275
|
this.dataStorage = dataStorage;
|
|
14273
14276
|
}
|
|
14274
14277
|
onPublish(callback) {
|
|
14275
14278
|
this.syncCallback = callback;
|
|
14276
14279
|
}
|
|
14277
|
-
onViewChanges(callback) {
|
|
14278
|
-
this.viewChangesCallbacks.add(callback);
|
|
14279
|
-
return () => {
|
|
14280
|
-
this.viewChangesCallbacks.delete(callback);
|
|
14281
|
-
};
|
|
14282
|
-
}
|
|
14283
14280
|
registerViews(views) {
|
|
14284
14281
|
this.views = views;
|
|
14285
14282
|
}
|
|
@@ -14347,19 +14344,7 @@ class LocalEventPublisher2 {
|
|
|
14347
14344
|
});
|
|
14348
14345
|
const viewChanges = await this.collectViewChanges(event);
|
|
14349
14346
|
allChanges.push(...viewChanges);
|
|
14350
|
-
|
|
14351
|
-
const committed = await this.dataStorage.commitChanges(allChanges, {
|
|
14352
|
-
captureRowsFor: viewStoreNames
|
|
14353
|
-
});
|
|
14354
|
-
if (committed.length > 0 && this.viewChangesCallbacks.size > 0) {
|
|
14355
|
-
for (const callback of this.viewChangesCallbacks) {
|
|
14356
|
-
try {
|
|
14357
|
-
callback(committed);
|
|
14358
|
-
} catch (error) {
|
|
14359
|
-
console.error(`[EventPublisher] onViewChanges callback error:`, error);
|
|
14360
|
-
}
|
|
14361
|
-
}
|
|
14362
|
-
}
|
|
14347
|
+
await this.dataStorage.commitChanges(allChanges);
|
|
14363
14348
|
await this.notifySubscribers(event);
|
|
14364
14349
|
if (this.syncCallback) {
|
|
14365
14350
|
this.syncCallback(event);
|
|
@@ -14740,9 +14725,8 @@ function typeValidatorBuilder(typeName, comparatorStrategy) {
|
|
|
14740
14725
|
}
|
|
14741
14726
|
|
|
14742
14727
|
class DataStorage {
|
|
14743
|
-
async commitChanges(changes
|
|
14728
|
+
async commitChanges(changes) {
|
|
14744
14729
|
await Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applyChanges(changes2)));
|
|
14745
|
-
return [];
|
|
14746
14730
|
}
|
|
14747
14731
|
}
|
|
14748
14732
|
|
|
@@ -15099,6 +15083,47 @@ function deepMerge(target, source) {
|
|
|
15099
15083
|
function isPlainObject(item) {
|
|
15100
15084
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
15101
15085
|
}
|
|
15086
|
+
function murmurHash(key, seed = 0) {
|
|
15087
|
+
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
15088
|
+
remainder = key.length & 3;
|
|
15089
|
+
bytes = key.length - remainder;
|
|
15090
|
+
h1 = seed;
|
|
15091
|
+
c1 = 3432918353;
|
|
15092
|
+
c2 = 461845907;
|
|
15093
|
+
i = 0;
|
|
15094
|
+
while (i < bytes) {
|
|
15095
|
+
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
15096
|
+
++i;
|
|
15097
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
15098
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
15099
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
15100
|
+
h1 ^= k1;
|
|
15101
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
15102
|
+
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
15103
|
+
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
15104
|
+
}
|
|
15105
|
+
k1 = 0;
|
|
15106
|
+
if (remainder >= 3) {
|
|
15107
|
+
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
15108
|
+
}
|
|
15109
|
+
if (remainder >= 2) {
|
|
15110
|
+
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
15111
|
+
}
|
|
15112
|
+
if (remainder >= 1) {
|
|
15113
|
+
k1 ^= key.charCodeAt(i) & 255;
|
|
15114
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
15115
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
15116
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
15117
|
+
h1 ^= k1;
|
|
15118
|
+
}
|
|
15119
|
+
h1 ^= key.length;
|
|
15120
|
+
h1 ^= h1 >>> 16;
|
|
15121
|
+
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
15122
|
+
h1 ^= h1 >>> 13;
|
|
15123
|
+
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
15124
|
+
h1 ^= h1 >>> 16;
|
|
15125
|
+
return h1 >>> 0;
|
|
15126
|
+
}
|
|
15102
15127
|
function resolveQueryChange(currentResult, event3, options) {
|
|
15103
15128
|
const index = currentResult.findIndex((e2) => e2._id === event3.id);
|
|
15104
15129
|
const isInCurrentResult = index !== -1;
|
|
@@ -15200,8 +15225,8 @@ class ObservableDataStorage {
|
|
|
15200
15225
|
getReadWriteTransaction() {
|
|
15201
15226
|
return this.source.getReadWriteTransaction();
|
|
15202
15227
|
}
|
|
15203
|
-
commitChanges(changes
|
|
15204
|
-
return this.source.commitChanges(changes
|
|
15228
|
+
commitChanges(changes) {
|
|
15229
|
+
return this.source.commitChanges(changes);
|
|
15205
15230
|
}
|
|
15206
15231
|
trackQuery(storeName, options, result, listener4) {
|
|
15207
15232
|
const key = this.getQueryKey(storeName, options);
|
|
@@ -15214,7 +15239,8 @@ class ObservableDataStorage {
|
|
|
15214
15239
|
}
|
|
15215
15240
|
handleStoreChange(storeName, events) {
|
|
15216
15241
|
let hasChanges = false;
|
|
15217
|
-
|
|
15242
|
+
const staleKeys = [];
|
|
15243
|
+
for (const [key, query] of this.trackedQueries) {
|
|
15218
15244
|
if (query.storeName !== storeName)
|
|
15219
15245
|
continue;
|
|
15220
15246
|
let currentResult = query.result;
|
|
@@ -15226,10 +15252,20 @@ class ObservableDataStorage {
|
|
|
15226
15252
|
queryChanged = true;
|
|
15227
15253
|
}
|
|
15228
15254
|
}
|
|
15229
|
-
if (queryChanged)
|
|
15230
|
-
|
|
15255
|
+
if (!queryChanged)
|
|
15256
|
+
continue;
|
|
15257
|
+
if (query.options.limit !== undefined && query.result.length === query.options.limit && currentResult.length < query.options.limit) {
|
|
15258
|
+
staleKeys.push(key);
|
|
15231
15259
|
hasChanges = true;
|
|
15260
|
+
continue;
|
|
15232
15261
|
}
|
|
15262
|
+
query.result = currentResult;
|
|
15263
|
+
hasChanges = true;
|
|
15264
|
+
}
|
|
15265
|
+
for (const key of staleKeys) {
|
|
15266
|
+
const query = this.trackedQueries.get(key);
|
|
15267
|
+
this.source.getStore(query.storeName).unsubscribe(query.listener);
|
|
15268
|
+
this.trackedQueries.delete(key);
|
|
15233
15269
|
}
|
|
15234
15270
|
if (hasChanges) {
|
|
15235
15271
|
this.onChange();
|
|
@@ -15499,243 +15535,136 @@ class Model2 {
|
|
|
15499
15535
|
return s;
|
|
15500
15536
|
}
|
|
15501
15537
|
}
|
|
15502
|
-
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
storeKey(viewName, scope) {
|
|
15510
|
-
return `${scope ?? DEFAULT_SCOPE}:${viewName}`;
|
|
15511
|
-
}
|
|
15512
|
-
registerViews(views) {
|
|
15513
|
-
this.views = views;
|
|
15514
|
-
}
|
|
15515
|
-
getStore(viewName, scope) {
|
|
15516
|
-
const key = this.storeKey(viewName, scope);
|
|
15517
|
-
if (!this.stores.has(key)) {
|
|
15518
|
-
this.stores.set(key, new StreamingStore);
|
|
15538
|
+
function applyQueryChanges(result, changes) {
|
|
15539
|
+
const next = [...result];
|
|
15540
|
+
for (const change of changes) {
|
|
15541
|
+
if (change.type === "delete") {
|
|
15542
|
+
const idx = next.findIndex((it) => it._id === change.id);
|
|
15543
|
+
if (idx !== -1)
|
|
15544
|
+
next.splice(idx, 1);
|
|
15519
15545
|
}
|
|
15520
|
-
return this.stores.get(key);
|
|
15521
15546
|
}
|
|
15522
|
-
|
|
15523
|
-
|
|
15524
|
-
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
if (pending) {
|
|
15529
|
-
clearTimeout(pending);
|
|
15530
|
-
this.pendingUnsubscribes.delete(key);
|
|
15547
|
+
for (const change of changes) {
|
|
15548
|
+
if (change.type === "set") {
|
|
15549
|
+
const idx = next.findIndex((it) => it._id === change.id);
|
|
15550
|
+
if (idx !== -1)
|
|
15551
|
+
next.splice(idx, 1);
|
|
15552
|
+
next.splice(change.index, 0, change.item);
|
|
15531
15553
|
}
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
|
|
15537
|
-
|
|
15554
|
+
}
|
|
15555
|
+
return next;
|
|
15556
|
+
}
|
|
15557
|
+
|
|
15558
|
+
class StreamingQueryCache {
|
|
15559
|
+
entries = new Map;
|
|
15560
|
+
static UNSUBSCRIBE_DELAY_MS = 5000;
|
|
15561
|
+
entryKey(descriptor, scope) {
|
|
15562
|
+
return `${scope ?? "default"}:${murmurHash(JSON.stringify(descriptor))}`;
|
|
15563
|
+
}
|
|
15564
|
+
subscribe(descriptor, scope, eventWire, onChange) {
|
|
15565
|
+
const key = this.entryKey(descriptor, scope);
|
|
15566
|
+
let entry = this.entries.get(key);
|
|
15567
|
+
if (entry) {
|
|
15568
|
+
if (entry.pendingUnsub) {
|
|
15569
|
+
clearTimeout(entry.pendingUnsub);
|
|
15570
|
+
entry.pendingUnsub = undefined;
|
|
15571
|
+
}
|
|
15572
|
+
entry.refCount++;
|
|
15573
|
+
} else {
|
|
15574
|
+
const newEntry = {
|
|
15575
|
+
result: undefined,
|
|
15576
|
+
hasResult: false,
|
|
15577
|
+
listeners: new Set,
|
|
15578
|
+
refCount: 1,
|
|
15579
|
+
subscriptionId: ""
|
|
15538
15580
|
};
|
|
15581
|
+
newEntry.subscriptionId = eventWire.subscribeQuery(descriptor, scope, {
|
|
15582
|
+
onSnapshot: (result) => {
|
|
15583
|
+
newEntry.result = result;
|
|
15584
|
+
newEntry.hasResult = true;
|
|
15585
|
+
this.notify(newEntry);
|
|
15586
|
+
},
|
|
15587
|
+
onChanges: (changes) => {
|
|
15588
|
+
if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
|
|
15589
|
+
return;
|
|
15590
|
+
}
|
|
15591
|
+
newEntry.result = applyQueryChanges(newEntry.result, changes);
|
|
15592
|
+
this.notify(newEntry);
|
|
15593
|
+
}
|
|
15594
|
+
});
|
|
15595
|
+
this.entries.set(key, newEntry);
|
|
15596
|
+
entry = newEntry;
|
|
15539
15597
|
}
|
|
15540
|
-
const
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
refCount: 1
|
|
15544
|
-
});
|
|
15598
|
+
const subscribed = entry;
|
|
15599
|
+
subscribed.listeners.add(onChange);
|
|
15600
|
+
let active = true;
|
|
15545
15601
|
return {
|
|
15546
|
-
|
|
15547
|
-
|
|
15602
|
+
read: () => ({
|
|
15603
|
+
result: subscribed.result,
|
|
15604
|
+
loading: !subscribed.hasResult
|
|
15605
|
+
}),
|
|
15606
|
+
unsubscribe: () => {
|
|
15607
|
+
if (!active)
|
|
15608
|
+
return;
|
|
15609
|
+
active = false;
|
|
15610
|
+
subscribed.listeners.delete(onChange);
|
|
15611
|
+
subscribed.refCount--;
|
|
15612
|
+
if (subscribed.refCount > 0)
|
|
15613
|
+
return;
|
|
15614
|
+
subscribed.pendingUnsub = setTimeout(() => {
|
|
15615
|
+
subscribed.pendingUnsub = undefined;
|
|
15616
|
+
if (subscribed.refCount > 0)
|
|
15617
|
+
return;
|
|
15618
|
+
eventWire.unsubscribeQuery(subscribed.subscriptionId);
|
|
15619
|
+
this.entries.delete(key);
|
|
15620
|
+
}, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
|
|
15621
|
+
}
|
|
15548
15622
|
};
|
|
15549
15623
|
}
|
|
15550
|
-
|
|
15551
|
-
const stream2 = this.activeStreams.get(key);
|
|
15552
|
-
if (!stream2)
|
|
15553
|
-
return;
|
|
15554
|
-
stream2.refCount--;
|
|
15555
|
-
if (stream2.refCount <= 0) {
|
|
15556
|
-
const timeout = setTimeout(() => {
|
|
15557
|
-
this.pendingUnsubscribes.delete(key);
|
|
15558
|
-
const current2 = this.activeStreams.get(key);
|
|
15559
|
-
if (current2 && current2.refCount <= 0) {
|
|
15560
|
-
current2.unsubscribe();
|
|
15561
|
-
this.activeStreams.delete(key);
|
|
15562
|
-
}
|
|
15563
|
-
}, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
|
|
15564
|
-
this.pendingUnsubscribes.set(key, timeout);
|
|
15565
|
-
}
|
|
15566
|
-
}
|
|
15567
|
-
subscribeView(viewName, eventWire, scope) {
|
|
15568
|
-
const key = this.storeKey(viewName, scope);
|
|
15569
|
-
const { unsubscribe } = this.registerStream(key, () => {
|
|
15570
|
-
const store = this.stores.get(key) ?? new StreamingStore;
|
|
15571
|
-
this.stores.set(key, store);
|
|
15572
|
-
eventWire.subscribeView(viewName, scope ?? DEFAULT_SCOPE, {
|
|
15573
|
-
onSnapshot: (items) => store.setAll(items),
|
|
15574
|
-
onChanges: (changes) => store.applyChanges(changes)
|
|
15575
|
-
});
|
|
15576
|
-
return {
|
|
15577
|
-
unsubscribe: () => eventWire.unsubscribeView(viewName, scope ?? DEFAULT_SCOPE)
|
|
15578
|
-
};
|
|
15579
|
-
});
|
|
15580
|
-
return unsubscribe;
|
|
15581
|
-
}
|
|
15582
|
-
invalidateScope(scope) {
|
|
15624
|
+
invalidateScope(scope, eventWire) {
|
|
15583
15625
|
const prefix = `${scope}:`;
|
|
15584
|
-
for (const [key,
|
|
15585
|
-
if (!key.startsWith(prefix))
|
|
15586
|
-
continue;
|
|
15587
|
-
clearTimeout(timeout);
|
|
15588
|
-
this.pendingUnsubscribes.delete(key);
|
|
15589
|
-
}
|
|
15590
|
-
for (const [key, stream2] of this.activeStreams) {
|
|
15591
|
-
if (!key.startsWith(prefix))
|
|
15592
|
-
continue;
|
|
15593
|
-
try {
|
|
15594
|
-
stream2.unsubscribe();
|
|
15595
|
-
} catch {}
|
|
15596
|
-
this.activeStreams.delete(key);
|
|
15597
|
-
}
|
|
15598
|
-
for (const [key, store] of this.stores) {
|
|
15626
|
+
for (const [key, entry] of this.entries) {
|
|
15599
15627
|
if (!key.startsWith(prefix))
|
|
15600
15628
|
continue;
|
|
15601
|
-
|
|
15629
|
+
if (entry.pendingUnsub)
|
|
15630
|
+
clearTimeout(entry.pendingUnsub);
|
|
15631
|
+
eventWire?.unsubscribeQuery(entry.subscriptionId);
|
|
15632
|
+
this.entries.delete(key);
|
|
15633
|
+
entry.result = undefined;
|
|
15634
|
+
entry.hasResult = false;
|
|
15635
|
+
this.notify(entry);
|
|
15602
15636
|
}
|
|
15603
15637
|
}
|
|
15604
|
-
|
|
15605
|
-
for (const
|
|
15606
|
-
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
continue;
|
|
15610
|
-
const suffix = `:${view3.name}`;
|
|
15611
|
-
for (const [key, store] of this.stores) {
|
|
15612
|
-
if (!key.endsWith(suffix))
|
|
15613
|
-
continue;
|
|
15614
|
-
const ctx = {
|
|
15615
|
-
set: async (id3, data) => {
|
|
15616
|
-
store.set(String(id3), { _id: String(id3), ...data });
|
|
15617
|
-
},
|
|
15618
|
-
modify: async (id3, data) => {
|
|
15619
|
-
store.modify(String(id3), data);
|
|
15620
|
-
},
|
|
15621
|
-
remove: async (id3) => {
|
|
15622
|
-
store.remove(String(id3));
|
|
15623
|
-
},
|
|
15624
|
-
find: async (options) => {
|
|
15625
|
-
return store.find(options);
|
|
15626
|
-
},
|
|
15627
|
-
findOne: async (where) => {
|
|
15628
|
-
return store.findOne(where);
|
|
15629
|
-
},
|
|
15630
|
-
$auth: {}
|
|
15631
|
-
};
|
|
15632
|
-
await handler(ctx, event3);
|
|
15633
|
-
}
|
|
15634
|
-
}
|
|
15635
|
-
}
|
|
15636
|
-
clear() {
|
|
15637
|
-
for (const stream2 of this.activeStreams.values()) {
|
|
15638
|
-
stream2.unsubscribe();
|
|
15639
|
-
}
|
|
15640
|
-
this.activeStreams.clear();
|
|
15641
|
-
for (const timeout of this.pendingUnsubscribes.values()) {
|
|
15642
|
-
clearTimeout(timeout);
|
|
15643
|
-
}
|
|
15644
|
-
this.pendingUnsubscribes.clear();
|
|
15645
|
-
for (const store of this.stores.values()) {
|
|
15646
|
-
store.clear();
|
|
15647
|
-
}
|
|
15648
|
-
}
|
|
15649
|
-
}
|
|
15650
|
-
|
|
15651
|
-
class StreamingStore {
|
|
15652
|
-
data = new Map;
|
|
15653
|
-
listeners = new Set;
|
|
15654
|
-
initialized = false;
|
|
15655
|
-
hasData() {
|
|
15656
|
-
return this.initialized;
|
|
15657
|
-
}
|
|
15658
|
-
setAll(items) {
|
|
15659
|
-
this.initialized = true;
|
|
15660
|
-
this.data.clear();
|
|
15661
|
-
for (const item of items) {
|
|
15662
|
-
this.data.set(item._id, item);
|
|
15638
|
+
clear(eventWire) {
|
|
15639
|
+
for (const entry of this.entries.values()) {
|
|
15640
|
+
if (entry.pendingUnsub)
|
|
15641
|
+
clearTimeout(entry.pendingUnsub);
|
|
15642
|
+
eventWire?.unsubscribeQuery(entry.subscriptionId);
|
|
15663
15643
|
}
|
|
15664
|
-
this.
|
|
15644
|
+
this.entries.clear();
|
|
15665
15645
|
}
|
|
15666
|
-
|
|
15667
|
-
|
|
15668
|
-
|
|
15669
|
-
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
} else if (event3.type === "delete") {
|
|
15673
|
-
this.data.delete(event3.id);
|
|
15646
|
+
notify(entry) {
|
|
15647
|
+
for (const listener4 of entry.listeners) {
|
|
15648
|
+
try {
|
|
15649
|
+
listener4();
|
|
15650
|
+
} catch (err3) {
|
|
15651
|
+
console.error(`[Arc] Query cache listener error:`, err3);
|
|
15674
15652
|
}
|
|
15675
15653
|
}
|
|
15676
|
-
this.notifyListeners(events);
|
|
15677
|
-
}
|
|
15678
|
-
set(id3, item) {
|
|
15679
|
-
this.data.set(id3, item);
|
|
15680
|
-
this.notifyListeners([{ type: "set", id: id3, item }]);
|
|
15681
|
-
}
|
|
15682
|
-
modify(id3, updates) {
|
|
15683
|
-
const existing = this.data.get(id3);
|
|
15684
|
-
if (existing) {
|
|
15685
|
-
const updated = { ...existing, ...updates };
|
|
15686
|
-
this.data.set(id3, updated);
|
|
15687
|
-
this.notifyListeners([{ type: "set", id: id3, item: updated }]);
|
|
15688
|
-
}
|
|
15689
|
-
}
|
|
15690
|
-
remove(id3) {
|
|
15691
|
-
if (this.data.delete(id3)) {
|
|
15692
|
-
this.notifyListeners([{ type: "delete", id: id3, item: null }]);
|
|
15693
|
-
}
|
|
15694
|
-
}
|
|
15695
|
-
clear() {
|
|
15696
|
-
this.initialized = false;
|
|
15697
|
-
this.data.clear();
|
|
15698
|
-
this.notifyListeners(null);
|
|
15699
|
-
}
|
|
15700
|
-
find(options = {}) {
|
|
15701
|
-
let results = Array.from(this.data.values());
|
|
15702
|
-
if (options.where) {
|
|
15703
|
-
results = results.filter((item) => checkItemMatchesWhere(item, options.where));
|
|
15704
|
-
}
|
|
15705
|
-
return applyOrderByAndLimit(results, options);
|
|
15706
|
-
}
|
|
15707
|
-
findOne(where) {
|
|
15708
|
-
const results = this.find({ where });
|
|
15709
|
-
return results[0];
|
|
15710
|
-
}
|
|
15711
|
-
subscribe(listener4) {
|
|
15712
|
-
this.listeners.add(listener4);
|
|
15713
|
-
return () => {
|
|
15714
|
-
this.listeners.delete(listener4);
|
|
15715
|
-
};
|
|
15716
|
-
}
|
|
15717
|
-
notifyListeners(events) {
|
|
15718
|
-
for (const listener4 of this.listeners) {
|
|
15719
|
-
listener4(events);
|
|
15720
|
-
}
|
|
15721
15654
|
}
|
|
15722
15655
|
}
|
|
15723
15656
|
|
|
15724
15657
|
class StreamingEventPublisher {
|
|
15725
|
-
cache;
|
|
15726
15658
|
eventWire;
|
|
15727
15659
|
views = [];
|
|
15728
15660
|
subscribers = new Map;
|
|
15729
|
-
constructor(
|
|
15730
|
-
this.cache = cache;
|
|
15661
|
+
constructor(eventWire) {
|
|
15731
15662
|
this.eventWire = eventWire;
|
|
15732
15663
|
}
|
|
15733
15664
|
registerViews(views) {
|
|
15734
15665
|
this.views = views;
|
|
15735
|
-
this.cache.registerViews(views);
|
|
15736
15666
|
}
|
|
15737
15667
|
async publish(event3) {
|
|
15738
|
-
await this.cache.applyEvent(event3);
|
|
15739
15668
|
await this.notifySubscribers(event3);
|
|
15740
15669
|
this.eventWire.syncEvents([
|
|
15741
15670
|
{
|
|
@@ -18142,7 +18071,7 @@ var Operation, PROXY_DRAFT, RAW_RETURN_SYMBOL, iteratorSymbol, dataTypes, intern
|
|
|
18142
18071
|
}
|
|
18143
18072
|
return returnValue(result);
|
|
18144
18073
|
};
|
|
18145
|
-
}, create, constructorString, TOKEN_PREFIX = "arc:token:", 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,
|
|
18074
|
+
}, create, constructorString, TOKEN_PREFIX = "arc:token:", 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) {
|
|
18146
18075
|
const user = typeHandlers(types22 || {});
|
|
18147
18076
|
return {
|
|
18148
18077
|
serializers: Object.assign({}, serializers, user.serializers),
|
|
@@ -19748,12 +19677,8 @@ var init_dist = __esm(() => {
|
|
|
19748
19677
|
}
|
|
19749
19678
|
return transaction.find(this.storeName, { where: { _id: id2 } }).then((results) => results[0]);
|
|
19750
19679
|
}
|
|
19751
|
-
async applyChangeAndReturnEvent(transaction, change, transactionCache
|
|
19680
|
+
async applyChangeAndReturnEvent(transaction, change, transactionCache) {
|
|
19752
19681
|
if (change.type === "set") {
|
|
19753
|
-
let existing;
|
|
19754
|
-
if (options?.captureRows) {
|
|
19755
|
-
existing = await this.readExisting(transaction, change.data._id, transactionCache);
|
|
19756
|
-
}
|
|
19757
19682
|
await transaction.set(this.storeName, change.data);
|
|
19758
19683
|
const item = this.deserialize ? this.deserialize(change.data) : change.data;
|
|
19759
19684
|
if (transactionCache) {
|
|
@@ -19766,16 +19691,10 @@ var init_dist = __esm(() => {
|
|
|
19766
19691
|
type: "set",
|
|
19767
19692
|
item: change.data,
|
|
19768
19693
|
id: change.data._id
|
|
19769
|
-
}
|
|
19770
|
-
oldRow: existing ?? null,
|
|
19771
|
-
newRow: change.data
|
|
19694
|
+
}
|
|
19772
19695
|
};
|
|
19773
19696
|
}
|
|
19774
19697
|
if (change.type === "delete") {
|
|
19775
|
-
let existing;
|
|
19776
|
-
if (options?.captureRows) {
|
|
19777
|
-
existing = await this.readExisting(transaction, change.id, transactionCache);
|
|
19778
|
-
}
|
|
19779
19698
|
await transaction.remove(this.storeName, change.id);
|
|
19780
19699
|
if (transactionCache) {
|
|
19781
19700
|
transactionCache.delete(`${this.storeName}:${change.id}`);
|
|
@@ -19787,9 +19706,7 @@ var init_dist = __esm(() => {
|
|
|
19787
19706
|
type: "delete",
|
|
19788
19707
|
item: null,
|
|
19789
19708
|
id: change.id
|
|
19790
|
-
}
|
|
19791
|
-
oldRow: existing ?? null,
|
|
19792
|
-
newRow: null
|
|
19709
|
+
}
|
|
19793
19710
|
};
|
|
19794
19711
|
}
|
|
19795
19712
|
if (change.type === "modify") {
|
|
@@ -19807,9 +19724,7 @@ var init_dist = __esm(() => {
|
|
|
19807
19724
|
type: "set",
|
|
19808
19725
|
item,
|
|
19809
19726
|
id: change.id
|
|
19810
|
-
}
|
|
19811
|
-
oldRow: existing ?? null,
|
|
19812
|
-
newRow: updated
|
|
19727
|
+
}
|
|
19813
19728
|
};
|
|
19814
19729
|
}
|
|
19815
19730
|
if (change.type === "mutate") {
|
|
@@ -19827,9 +19742,7 @@ var init_dist = __esm(() => {
|
|
|
19827
19742
|
type: "set",
|
|
19828
19743
|
item,
|
|
19829
19744
|
id: change.id
|
|
19830
|
-
}
|
|
19831
|
-
oldRow: existing ?? null,
|
|
19832
|
-
newRow: updated
|
|
19745
|
+
}
|
|
19833
19746
|
};
|
|
19834
19747
|
}
|
|
19835
19748
|
throw new Error("Unknown change type");
|
|
@@ -19906,22 +19819,17 @@ var init_dist = __esm(() => {
|
|
|
19906
19819
|
applySerializedChanges(changes) {
|
|
19907
19820
|
return Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applySerializedChanges(changes2)));
|
|
19908
19821
|
}
|
|
19909
|
-
async commitChanges(changes
|
|
19822
|
+
async commitChanges(changes) {
|
|
19910
19823
|
const transaction = await this.getReadWriteTransaction();
|
|
19911
19824
|
const transactionCache = new Map;
|
|
19912
19825
|
const eventsByStore = new Map;
|
|
19913
|
-
const committed = [];
|
|
19914
19826
|
for (const { store, changes: storeChanges } of changes) {
|
|
19915
19827
|
const storeState = this.getStore(store);
|
|
19916
19828
|
const storeEvents = [];
|
|
19917
|
-
const capture = options?.captureRowsFor?.has(store) ?? false;
|
|
19918
19829
|
for (const change of storeChanges) {
|
|
19919
|
-
const { event: event3
|
|
19830
|
+
const { event: event3 } = await storeState.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
19920
19831
|
if (event3)
|
|
19921
19832
|
storeEvents.push(event3);
|
|
19922
|
-
if (capture) {
|
|
19923
|
-
committed.push({ store, id: event3.id, oldRow, newRow });
|
|
19924
|
-
}
|
|
19925
19833
|
}
|
|
19926
19834
|
if (storeEvents.length > 0) {
|
|
19927
19835
|
eventsByStore.set(store, storeEvents);
|
|
@@ -19932,7 +19840,6 @@ var init_dist = __esm(() => {
|
|
|
19932
19840
|
const storeState = this.getStore(store);
|
|
19933
19841
|
storeState.notifyListenersPublic(events);
|
|
19934
19842
|
}
|
|
19935
|
-
return committed;
|
|
19936
19843
|
}
|
|
19937
19844
|
fork() {
|
|
19938
19845
|
return new ForkedDataStorage(this);
|
|
@@ -21448,7 +21355,8 @@ class EventWire2 {
|
|
|
21448
21355
|
onSyncedCallback;
|
|
21449
21356
|
reconnectTimeout;
|
|
21450
21357
|
syncRequested = false;
|
|
21451
|
-
|
|
21358
|
+
querySubscriptions = new Map;
|
|
21359
|
+
querySubCounter = 0;
|
|
21452
21360
|
enableEventSync;
|
|
21453
21361
|
constructor(baseUrl, options) {
|
|
21454
21362
|
this.baseUrl = baseUrl;
|
|
@@ -21503,7 +21411,7 @@ class EventWire2 {
|
|
|
21503
21411
|
this.requestSync();
|
|
21504
21412
|
}
|
|
21505
21413
|
this.flushPendingEvents();
|
|
21506
|
-
this.
|
|
21414
|
+
this.sendAllQuerySubscriptions();
|
|
21507
21415
|
} else {
|
|
21508
21416
|
console.log(`[EventWire] onopen called but ws is not OPEN, readyState:`, this.ws?.readyState);
|
|
21509
21417
|
}
|
|
@@ -21579,24 +21487,29 @@ class EventWire2 {
|
|
|
21579
21487
|
onSynced(callback) {
|
|
21580
21488
|
this.onSyncedCallback = callback;
|
|
21581
21489
|
}
|
|
21582
|
-
|
|
21583
|
-
const
|
|
21584
|
-
this.
|
|
21490
|
+
subscribeQuery(descriptor, scope, callbacks) {
|
|
21491
|
+
const subscriptionId = `qs_${this.instanceId}_${++this.querySubCounter}`;
|
|
21492
|
+
this.querySubscriptions.set(subscriptionId, {
|
|
21493
|
+
descriptor,
|
|
21494
|
+
scope,
|
|
21495
|
+
callbacks
|
|
21496
|
+
});
|
|
21585
21497
|
if (this.state === "connected" && this.ws) {
|
|
21586
21498
|
this.ws.send(JSON.stringify({
|
|
21587
|
-
type: "subscribe-
|
|
21588
|
-
|
|
21499
|
+
type: "subscribe-query",
|
|
21500
|
+
subscriptionId,
|
|
21501
|
+
descriptor,
|
|
21589
21502
|
scope
|
|
21590
21503
|
}));
|
|
21591
21504
|
}
|
|
21505
|
+
return subscriptionId;
|
|
21592
21506
|
}
|
|
21593
|
-
|
|
21594
|
-
this.
|
|
21507
|
+
unsubscribeQuery(subscriptionId) {
|
|
21508
|
+
this.querySubscriptions.delete(subscriptionId);
|
|
21595
21509
|
if (this.state === "connected" && this.ws) {
|
|
21596
21510
|
this.ws.send(JSON.stringify({
|
|
21597
|
-
type: "unsubscribe-
|
|
21598
|
-
|
|
21599
|
-
scope
|
|
21511
|
+
type: "unsubscribe-query",
|
|
21512
|
+
subscriptionId
|
|
21600
21513
|
}));
|
|
21601
21514
|
}
|
|
21602
21515
|
}
|
|
@@ -21631,17 +21544,17 @@ class EventWire2 {
|
|
|
21631
21544
|
this.lastHostEventId = message.lastHostEventId;
|
|
21632
21545
|
}
|
|
21633
21546
|
break;
|
|
21634
|
-
case "
|
|
21635
|
-
const sub = this.
|
|
21547
|
+
case "query-snapshot": {
|
|
21548
|
+
const sub = this.querySubscriptions.get(message.subscriptionId);
|
|
21636
21549
|
if (sub) {
|
|
21637
|
-
sub.onSnapshot(message.
|
|
21550
|
+
sub.callbacks.onSnapshot(message.result ?? null);
|
|
21638
21551
|
}
|
|
21639
21552
|
break;
|
|
21640
21553
|
}
|
|
21641
|
-
case "
|
|
21642
|
-
const sub = this.
|
|
21554
|
+
case "query-changes": {
|
|
21555
|
+
const sub = this.querySubscriptions.get(message.subscriptionId);
|
|
21643
21556
|
if (sub && Array.isArray(message.changes)) {
|
|
21644
|
-
sub.onChanges(message.changes);
|
|
21557
|
+
sub.callbacks.onChanges(message.changes);
|
|
21645
21558
|
}
|
|
21646
21559
|
break;
|
|
21647
21560
|
}
|
|
@@ -21669,17 +21582,15 @@ class EventWire2 {
|
|
|
21669
21582
|
this.pendingEvents = [];
|
|
21670
21583
|
}
|
|
21671
21584
|
}
|
|
21672
|
-
|
|
21585
|
+
sendAllQuerySubscriptions() {
|
|
21673
21586
|
if (!this.ws || this.state !== "connected")
|
|
21674
21587
|
return;
|
|
21675
|
-
for (const
|
|
21676
|
-
const sepIdx = key.indexOf(":");
|
|
21677
|
-
const scope = key.slice(0, sepIdx);
|
|
21678
|
-
const element = key.slice(sepIdx + 1);
|
|
21588
|
+
for (const [subscriptionId, sub] of this.querySubscriptions) {
|
|
21679
21589
|
this.ws.send(JSON.stringify({
|
|
21680
|
-
type: "subscribe-
|
|
21681
|
-
|
|
21682
|
-
|
|
21590
|
+
type: "subscribe-query",
|
|
21591
|
+
subscriptionId,
|
|
21592
|
+
descriptor: sub.descriptor,
|
|
21593
|
+
scope: sub.scope
|
|
21683
21594
|
}));
|
|
21684
21595
|
}
|
|
21685
21596
|
}
|
|
@@ -21698,19 +21609,12 @@ class LocalEventPublisher3 {
|
|
|
21698
21609
|
views = [];
|
|
21699
21610
|
syncCallback;
|
|
21700
21611
|
subscribers = new Map;
|
|
21701
|
-
viewChangesCallbacks = new Set;
|
|
21702
21612
|
constructor(dataStorage) {
|
|
21703
21613
|
this.dataStorage = dataStorage;
|
|
21704
21614
|
}
|
|
21705
21615
|
onPublish(callback) {
|
|
21706
21616
|
this.syncCallback = callback;
|
|
21707
21617
|
}
|
|
21708
|
-
onViewChanges(callback) {
|
|
21709
|
-
this.viewChangesCallbacks.add(callback);
|
|
21710
|
-
return () => {
|
|
21711
|
-
this.viewChangesCallbacks.delete(callback);
|
|
21712
|
-
};
|
|
21713
|
-
}
|
|
21714
21618
|
registerViews(views) {
|
|
21715
21619
|
this.views = views;
|
|
21716
21620
|
}
|
|
@@ -21778,19 +21682,7 @@ class LocalEventPublisher3 {
|
|
|
21778
21682
|
});
|
|
21779
21683
|
const viewChanges = await this.collectViewChanges(event);
|
|
21780
21684
|
allChanges.push(...viewChanges);
|
|
21781
|
-
|
|
21782
|
-
const committed = await this.dataStorage.commitChanges(allChanges, {
|
|
21783
|
-
captureRowsFor: viewStoreNames
|
|
21784
|
-
});
|
|
21785
|
-
if (committed.length > 0 && this.viewChangesCallbacks.size > 0) {
|
|
21786
|
-
for (const callback of this.viewChangesCallbacks) {
|
|
21787
|
-
try {
|
|
21788
|
-
callback(committed);
|
|
21789
|
-
} catch (error) {
|
|
21790
|
-
console.error(`[EventPublisher] onViewChanges callback error:`, error);
|
|
21791
|
-
}
|
|
21792
|
-
}
|
|
21793
|
-
}
|
|
21685
|
+
await this.dataStorage.commitChanges(allChanges);
|
|
21794
21686
|
await this.notifySubscribers(event);
|
|
21795
21687
|
if (this.syncCallback) {
|
|
21796
21688
|
this.syncCallback(event);
|
|
@@ -22171,9 +22063,8 @@ function typeValidatorBuilder2(typeName, comparatorStrategy) {
|
|
|
22171
22063
|
}
|
|
22172
22064
|
|
|
22173
22065
|
class DataStorage2 {
|
|
22174
|
-
async commitChanges(changes
|
|
22066
|
+
async commitChanges(changes) {
|
|
22175
22067
|
await Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applyChanges(changes2)));
|
|
22176
|
-
return [];
|
|
22177
22068
|
}
|
|
22178
22069
|
}
|
|
22179
22070
|
|
|
@@ -22530,6 +22421,47 @@ function deepMerge2(target, source) {
|
|
|
22530
22421
|
function isPlainObject2(item) {
|
|
22531
22422
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
22532
22423
|
}
|
|
22424
|
+
function murmurHash2(key, seed = 0) {
|
|
22425
|
+
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
22426
|
+
remainder = key.length & 3;
|
|
22427
|
+
bytes = key.length - remainder;
|
|
22428
|
+
h1 = seed;
|
|
22429
|
+
c1 = 3432918353;
|
|
22430
|
+
c2 = 461845907;
|
|
22431
|
+
i = 0;
|
|
22432
|
+
while (i < bytes) {
|
|
22433
|
+
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
22434
|
+
++i;
|
|
22435
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
22436
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
22437
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
22438
|
+
h1 ^= k1;
|
|
22439
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
22440
|
+
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
22441
|
+
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
22442
|
+
}
|
|
22443
|
+
k1 = 0;
|
|
22444
|
+
if (remainder >= 3) {
|
|
22445
|
+
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
22446
|
+
}
|
|
22447
|
+
if (remainder >= 2) {
|
|
22448
|
+
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
22449
|
+
}
|
|
22450
|
+
if (remainder >= 1) {
|
|
22451
|
+
k1 ^= key.charCodeAt(i) & 255;
|
|
22452
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
22453
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
22454
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
22455
|
+
h1 ^= k1;
|
|
22456
|
+
}
|
|
22457
|
+
h1 ^= key.length;
|
|
22458
|
+
h1 ^= h1 >>> 16;
|
|
22459
|
+
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
22460
|
+
h1 ^= h1 >>> 13;
|
|
22461
|
+
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
22462
|
+
h1 ^= h1 >>> 16;
|
|
22463
|
+
return h1 >>> 0;
|
|
22464
|
+
}
|
|
22533
22465
|
function resolveQueryChange2(currentResult, event3, options) {
|
|
22534
22466
|
const index = currentResult.findIndex((e2) => e2._id === event3.id);
|
|
22535
22467
|
const isInCurrentResult = index !== -1;
|
|
@@ -22631,8 +22563,8 @@ class ObservableDataStorage2 {
|
|
|
22631
22563
|
getReadWriteTransaction() {
|
|
22632
22564
|
return this.source.getReadWriteTransaction();
|
|
22633
22565
|
}
|
|
22634
|
-
commitChanges(changes
|
|
22635
|
-
return this.source.commitChanges(changes
|
|
22566
|
+
commitChanges(changes) {
|
|
22567
|
+
return this.source.commitChanges(changes);
|
|
22636
22568
|
}
|
|
22637
22569
|
trackQuery(storeName, options, result, listener4) {
|
|
22638
22570
|
const key = this.getQueryKey(storeName, options);
|
|
@@ -22645,7 +22577,8 @@ class ObservableDataStorage2 {
|
|
|
22645
22577
|
}
|
|
22646
22578
|
handleStoreChange(storeName, events) {
|
|
22647
22579
|
let hasChanges = false;
|
|
22648
|
-
|
|
22580
|
+
const staleKeys = [];
|
|
22581
|
+
for (const [key, query] of this.trackedQueries) {
|
|
22649
22582
|
if (query.storeName !== storeName)
|
|
22650
22583
|
continue;
|
|
22651
22584
|
let currentResult = query.result;
|
|
@@ -22657,10 +22590,20 @@ class ObservableDataStorage2 {
|
|
|
22657
22590
|
queryChanged = true;
|
|
22658
22591
|
}
|
|
22659
22592
|
}
|
|
22660
|
-
if (queryChanged)
|
|
22661
|
-
|
|
22593
|
+
if (!queryChanged)
|
|
22594
|
+
continue;
|
|
22595
|
+
if (query.options.limit !== undefined && query.result.length === query.options.limit && currentResult.length < query.options.limit) {
|
|
22596
|
+
staleKeys.push(key);
|
|
22662
22597
|
hasChanges = true;
|
|
22598
|
+
continue;
|
|
22663
22599
|
}
|
|
22600
|
+
query.result = currentResult;
|
|
22601
|
+
hasChanges = true;
|
|
22602
|
+
}
|
|
22603
|
+
for (const key of staleKeys) {
|
|
22604
|
+
const query = this.trackedQueries.get(key);
|
|
22605
|
+
this.source.getStore(query.storeName).unsubscribe(query.listener);
|
|
22606
|
+
this.trackedQueries.delete(key);
|
|
22664
22607
|
}
|
|
22665
22608
|
if (hasChanges) {
|
|
22666
22609
|
this.onChange();
|
|
@@ -22930,243 +22873,136 @@ class Model3 {
|
|
|
22930
22873
|
return s;
|
|
22931
22874
|
}
|
|
22932
22875
|
}
|
|
22933
|
-
|
|
22934
|
-
|
|
22935
|
-
|
|
22936
|
-
|
|
22937
|
-
|
|
22938
|
-
|
|
22939
|
-
|
|
22940
|
-
storeKey(viewName, scope) {
|
|
22941
|
-
return `${scope ?? DEFAULT_SCOPE2}:${viewName}`;
|
|
22942
|
-
}
|
|
22943
|
-
registerViews(views) {
|
|
22944
|
-
this.views = views;
|
|
22945
|
-
}
|
|
22946
|
-
getStore(viewName, scope) {
|
|
22947
|
-
const key = this.storeKey(viewName, scope);
|
|
22948
|
-
if (!this.stores.has(key)) {
|
|
22949
|
-
this.stores.set(key, new StreamingStore2);
|
|
22876
|
+
function applyQueryChanges2(result, changes) {
|
|
22877
|
+
const next = [...result];
|
|
22878
|
+
for (const change of changes) {
|
|
22879
|
+
if (change.type === "delete") {
|
|
22880
|
+
const idx = next.findIndex((it) => it._id === change.id);
|
|
22881
|
+
if (idx !== -1)
|
|
22882
|
+
next.splice(idx, 1);
|
|
22950
22883
|
}
|
|
22951
|
-
return this.stores.get(key);
|
|
22952
|
-
}
|
|
22953
|
-
hasData(viewName, scope) {
|
|
22954
|
-
const store = this.stores.get(this.storeKey(viewName, scope));
|
|
22955
|
-
return store ? store.hasData() : false;
|
|
22956
22884
|
}
|
|
22957
|
-
|
|
22958
|
-
|
|
22959
|
-
|
|
22960
|
-
|
|
22961
|
-
|
|
22885
|
+
for (const change of changes) {
|
|
22886
|
+
if (change.type === "set") {
|
|
22887
|
+
const idx = next.findIndex((it) => it._id === change.id);
|
|
22888
|
+
if (idx !== -1)
|
|
22889
|
+
next.splice(idx, 1);
|
|
22890
|
+
next.splice(change.index, 0, change.item);
|
|
22962
22891
|
}
|
|
22963
|
-
|
|
22964
|
-
|
|
22965
|
-
|
|
22966
|
-
|
|
22967
|
-
|
|
22968
|
-
|
|
22892
|
+
}
|
|
22893
|
+
return next;
|
|
22894
|
+
}
|
|
22895
|
+
|
|
22896
|
+
class StreamingQueryCache2 {
|
|
22897
|
+
entries = new Map;
|
|
22898
|
+
static UNSUBSCRIBE_DELAY_MS = 5000;
|
|
22899
|
+
entryKey(descriptor, scope) {
|
|
22900
|
+
return `${scope ?? "default"}:${murmurHash2(JSON.stringify(descriptor))}`;
|
|
22901
|
+
}
|
|
22902
|
+
subscribe(descriptor, scope, eventWire, onChange) {
|
|
22903
|
+
const key = this.entryKey(descriptor, scope);
|
|
22904
|
+
let entry = this.entries.get(key);
|
|
22905
|
+
if (entry) {
|
|
22906
|
+
if (entry.pendingUnsub) {
|
|
22907
|
+
clearTimeout(entry.pendingUnsub);
|
|
22908
|
+
entry.pendingUnsub = undefined;
|
|
22909
|
+
}
|
|
22910
|
+
entry.refCount++;
|
|
22911
|
+
} else {
|
|
22912
|
+
const newEntry = {
|
|
22913
|
+
result: undefined,
|
|
22914
|
+
hasResult: false,
|
|
22915
|
+
listeners: new Set,
|
|
22916
|
+
refCount: 1,
|
|
22917
|
+
subscriptionId: ""
|
|
22969
22918
|
};
|
|
22919
|
+
newEntry.subscriptionId = eventWire.subscribeQuery(descriptor, scope, {
|
|
22920
|
+
onSnapshot: (result) => {
|
|
22921
|
+
newEntry.result = result;
|
|
22922
|
+
newEntry.hasResult = true;
|
|
22923
|
+
this.notify(newEntry);
|
|
22924
|
+
},
|
|
22925
|
+
onChanges: (changes) => {
|
|
22926
|
+
if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
|
|
22927
|
+
return;
|
|
22928
|
+
}
|
|
22929
|
+
newEntry.result = applyQueryChanges2(newEntry.result, changes);
|
|
22930
|
+
this.notify(newEntry);
|
|
22931
|
+
}
|
|
22932
|
+
});
|
|
22933
|
+
this.entries.set(key, newEntry);
|
|
22934
|
+
entry = newEntry;
|
|
22970
22935
|
}
|
|
22971
|
-
const
|
|
22972
|
-
|
|
22973
|
-
|
|
22974
|
-
refCount: 1
|
|
22975
|
-
});
|
|
22936
|
+
const subscribed = entry;
|
|
22937
|
+
subscribed.listeners.add(onChange);
|
|
22938
|
+
let active = true;
|
|
22976
22939
|
return {
|
|
22977
|
-
|
|
22978
|
-
|
|
22940
|
+
read: () => ({
|
|
22941
|
+
result: subscribed.result,
|
|
22942
|
+
loading: !subscribed.hasResult
|
|
22943
|
+
}),
|
|
22944
|
+
unsubscribe: () => {
|
|
22945
|
+
if (!active)
|
|
22946
|
+
return;
|
|
22947
|
+
active = false;
|
|
22948
|
+
subscribed.listeners.delete(onChange);
|
|
22949
|
+
subscribed.refCount--;
|
|
22950
|
+
if (subscribed.refCount > 0)
|
|
22951
|
+
return;
|
|
22952
|
+
subscribed.pendingUnsub = setTimeout(() => {
|
|
22953
|
+
subscribed.pendingUnsub = undefined;
|
|
22954
|
+
if (subscribed.refCount > 0)
|
|
22955
|
+
return;
|
|
22956
|
+
eventWire.unsubscribeQuery(subscribed.subscriptionId);
|
|
22957
|
+
this.entries.delete(key);
|
|
22958
|
+
}, StreamingQueryCache2.UNSUBSCRIBE_DELAY_MS);
|
|
22959
|
+
}
|
|
22979
22960
|
};
|
|
22980
22961
|
}
|
|
22981
|
-
|
|
22982
|
-
const stream2 = this.activeStreams.get(key);
|
|
22983
|
-
if (!stream2)
|
|
22984
|
-
return;
|
|
22985
|
-
stream2.refCount--;
|
|
22986
|
-
if (stream2.refCount <= 0) {
|
|
22987
|
-
const timeout = setTimeout(() => {
|
|
22988
|
-
this.pendingUnsubscribes.delete(key);
|
|
22989
|
-
const current22 = this.activeStreams.get(key);
|
|
22990
|
-
if (current22 && current22.refCount <= 0) {
|
|
22991
|
-
current22.unsubscribe();
|
|
22992
|
-
this.activeStreams.delete(key);
|
|
22993
|
-
}
|
|
22994
|
-
}, StreamingQueryCache2.UNSUBSCRIBE_DELAY_MS);
|
|
22995
|
-
this.pendingUnsubscribes.set(key, timeout);
|
|
22996
|
-
}
|
|
22997
|
-
}
|
|
22998
|
-
subscribeView(viewName, eventWire, scope) {
|
|
22999
|
-
const key = this.storeKey(viewName, scope);
|
|
23000
|
-
const { unsubscribe } = this.registerStream(key, () => {
|
|
23001
|
-
const store = this.stores.get(key) ?? new StreamingStore2;
|
|
23002
|
-
this.stores.set(key, store);
|
|
23003
|
-
eventWire.subscribeView(viewName, scope ?? DEFAULT_SCOPE2, {
|
|
23004
|
-
onSnapshot: (items) => store.setAll(items),
|
|
23005
|
-
onChanges: (changes) => store.applyChanges(changes)
|
|
23006
|
-
});
|
|
23007
|
-
return {
|
|
23008
|
-
unsubscribe: () => eventWire.unsubscribeView(viewName, scope ?? DEFAULT_SCOPE2)
|
|
23009
|
-
};
|
|
23010
|
-
});
|
|
23011
|
-
return unsubscribe;
|
|
23012
|
-
}
|
|
23013
|
-
invalidateScope(scope) {
|
|
22962
|
+
invalidateScope(scope, eventWire) {
|
|
23014
22963
|
const prefix = `${scope}:`;
|
|
23015
|
-
for (const [key,
|
|
23016
|
-
if (!key.startsWith(prefix))
|
|
23017
|
-
continue;
|
|
23018
|
-
clearTimeout(timeout);
|
|
23019
|
-
this.pendingUnsubscribes.delete(key);
|
|
23020
|
-
}
|
|
23021
|
-
for (const [key, stream2] of this.activeStreams) {
|
|
23022
|
-
if (!key.startsWith(prefix))
|
|
23023
|
-
continue;
|
|
23024
|
-
try {
|
|
23025
|
-
stream2.unsubscribe();
|
|
23026
|
-
} catch {}
|
|
23027
|
-
this.activeStreams.delete(key);
|
|
23028
|
-
}
|
|
23029
|
-
for (const [key, store] of this.stores) {
|
|
22964
|
+
for (const [key, entry] of this.entries) {
|
|
23030
22965
|
if (!key.startsWith(prefix))
|
|
23031
22966
|
continue;
|
|
23032
|
-
|
|
23033
|
-
|
|
23034
|
-
|
|
23035
|
-
|
|
23036
|
-
|
|
23037
|
-
|
|
23038
|
-
|
|
23039
|
-
if (!handler)
|
|
23040
|
-
continue;
|
|
23041
|
-
const suffix = `:${view3.name}`;
|
|
23042
|
-
for (const [key, store] of this.stores) {
|
|
23043
|
-
if (!key.endsWith(suffix))
|
|
23044
|
-
continue;
|
|
23045
|
-
const ctx = {
|
|
23046
|
-
set: async (id3, data) => {
|
|
23047
|
-
store.set(String(id3), { _id: String(id3), ...data });
|
|
23048
|
-
},
|
|
23049
|
-
modify: async (id3, data) => {
|
|
23050
|
-
store.modify(String(id3), data);
|
|
23051
|
-
},
|
|
23052
|
-
remove: async (id3) => {
|
|
23053
|
-
store.remove(String(id3));
|
|
23054
|
-
},
|
|
23055
|
-
find: async (options) => {
|
|
23056
|
-
return store.find(options);
|
|
23057
|
-
},
|
|
23058
|
-
findOne: async (where) => {
|
|
23059
|
-
return store.findOne(where);
|
|
23060
|
-
},
|
|
23061
|
-
$auth: {}
|
|
23062
|
-
};
|
|
23063
|
-
await handler(ctx, event3);
|
|
23064
|
-
}
|
|
23065
|
-
}
|
|
23066
|
-
}
|
|
23067
|
-
clear() {
|
|
23068
|
-
for (const stream2 of this.activeStreams.values()) {
|
|
23069
|
-
stream2.unsubscribe();
|
|
23070
|
-
}
|
|
23071
|
-
this.activeStreams.clear();
|
|
23072
|
-
for (const timeout of this.pendingUnsubscribes.values()) {
|
|
23073
|
-
clearTimeout(timeout);
|
|
22967
|
+
if (entry.pendingUnsub)
|
|
22968
|
+
clearTimeout(entry.pendingUnsub);
|
|
22969
|
+
eventWire?.unsubscribeQuery(entry.subscriptionId);
|
|
22970
|
+
this.entries.delete(key);
|
|
22971
|
+
entry.result = undefined;
|
|
22972
|
+
entry.hasResult = false;
|
|
22973
|
+
this.notify(entry);
|
|
23074
22974
|
}
|
|
23075
|
-
this.pendingUnsubscribes.clear();
|
|
23076
|
-
for (const store of this.stores.values()) {
|
|
23077
|
-
store.clear();
|
|
23078
|
-
}
|
|
23079
|
-
}
|
|
23080
|
-
}
|
|
23081
|
-
|
|
23082
|
-
class StreamingStore2 {
|
|
23083
|
-
data = new Map;
|
|
23084
|
-
listeners = new Set;
|
|
23085
|
-
initialized = false;
|
|
23086
|
-
hasData() {
|
|
23087
|
-
return this.initialized;
|
|
23088
22975
|
}
|
|
23089
|
-
|
|
23090
|
-
this.
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
22976
|
+
clear(eventWire) {
|
|
22977
|
+
for (const entry of this.entries.values()) {
|
|
22978
|
+
if (entry.pendingUnsub)
|
|
22979
|
+
clearTimeout(entry.pendingUnsub);
|
|
22980
|
+
eventWire?.unsubscribeQuery(entry.subscriptionId);
|
|
23094
22981
|
}
|
|
23095
|
-
this.
|
|
22982
|
+
this.entries.clear();
|
|
23096
22983
|
}
|
|
23097
|
-
|
|
23098
|
-
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
} else if (event3.type === "delete") {
|
|
23104
|
-
this.data.delete(event3.id);
|
|
22984
|
+
notify(entry) {
|
|
22985
|
+
for (const listener4 of entry.listeners) {
|
|
22986
|
+
try {
|
|
22987
|
+
listener4();
|
|
22988
|
+
} catch (err3) {
|
|
22989
|
+
console.error(`[Arc] Query cache listener error:`, err3);
|
|
23105
22990
|
}
|
|
23106
22991
|
}
|
|
23107
|
-
this.notifyListeners(events);
|
|
23108
|
-
}
|
|
23109
|
-
set(id3, item) {
|
|
23110
|
-
this.data.set(id3, item);
|
|
23111
|
-
this.notifyListeners([{ type: "set", id: id3, item }]);
|
|
23112
|
-
}
|
|
23113
|
-
modify(id3, updates) {
|
|
23114
|
-
const existing = this.data.get(id3);
|
|
23115
|
-
if (existing) {
|
|
23116
|
-
const updated = { ...existing, ...updates };
|
|
23117
|
-
this.data.set(id3, updated);
|
|
23118
|
-
this.notifyListeners([{ type: "set", id: id3, item: updated }]);
|
|
23119
|
-
}
|
|
23120
|
-
}
|
|
23121
|
-
remove(id3) {
|
|
23122
|
-
if (this.data.delete(id3)) {
|
|
23123
|
-
this.notifyListeners([{ type: "delete", id: id3, item: null }]);
|
|
23124
|
-
}
|
|
23125
|
-
}
|
|
23126
|
-
clear() {
|
|
23127
|
-
this.initialized = false;
|
|
23128
|
-
this.data.clear();
|
|
23129
|
-
this.notifyListeners(null);
|
|
23130
|
-
}
|
|
23131
|
-
find(options = {}) {
|
|
23132
|
-
let results = Array.from(this.data.values());
|
|
23133
|
-
if (options.where) {
|
|
23134
|
-
results = results.filter((item) => checkItemMatchesWhere2(item, options.where));
|
|
23135
|
-
}
|
|
23136
|
-
return applyOrderByAndLimit2(results, options);
|
|
23137
|
-
}
|
|
23138
|
-
findOne(where) {
|
|
23139
|
-
const results = this.find({ where });
|
|
23140
|
-
return results[0];
|
|
23141
|
-
}
|
|
23142
|
-
subscribe(listener4) {
|
|
23143
|
-
this.listeners.add(listener4);
|
|
23144
|
-
return () => {
|
|
23145
|
-
this.listeners.delete(listener4);
|
|
23146
|
-
};
|
|
23147
|
-
}
|
|
23148
|
-
notifyListeners(events) {
|
|
23149
|
-
for (const listener4 of this.listeners) {
|
|
23150
|
-
listener4(events);
|
|
23151
|
-
}
|
|
23152
22992
|
}
|
|
23153
22993
|
}
|
|
23154
22994
|
|
|
23155
22995
|
class StreamingEventPublisher2 {
|
|
23156
|
-
cache;
|
|
23157
22996
|
eventWire;
|
|
23158
22997
|
views = [];
|
|
23159
22998
|
subscribers = new Map;
|
|
23160
|
-
constructor(
|
|
23161
|
-
this.cache = cache;
|
|
22999
|
+
constructor(eventWire) {
|
|
23162
23000
|
this.eventWire = eventWire;
|
|
23163
23001
|
}
|
|
23164
23002
|
registerViews(views) {
|
|
23165
23003
|
this.views = views;
|
|
23166
|
-
this.cache.registerViews(views);
|
|
23167
23004
|
}
|
|
23168
23005
|
async publish(event3) {
|
|
23169
|
-
await this.cache.applyEvent(event3);
|
|
23170
23006
|
await this.notifySubscribers(event3);
|
|
23171
23007
|
this.eventWire.syncEvents([
|
|
23172
23008
|
{
|
|
@@ -24049,7 +23885,7 @@ var Operation2, PROXY_DRAFT2, RAW_RETURN_SYMBOL2, iteratorSymbol2, dataTypes2, i
|
|
|
24049
23885
|
}
|
|
24050
23886
|
return returnValue(result);
|
|
24051
23887
|
};
|
|
24052
|
-
}, create2, constructorString2, TOKEN_PREFIX2 = "arc:token:", 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,
|
|
23888
|
+
}, create2, constructorString2, TOKEN_PREFIX2 = "arc:token:", 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) => {
|
|
24053
23889
|
return async (context) => {
|
|
24054
23890
|
const adapter = new SQLiteAdapter(db, context);
|
|
24055
23891
|
await adapter.initialize();
|
|
@@ -25614,12 +25450,8 @@ var init_dist2 = __esm(() => {
|
|
|
25614
25450
|
}
|
|
25615
25451
|
return transaction.find(this.storeName, { where: { _id: id22 } }).then((results) => results[0]);
|
|
25616
25452
|
}
|
|
25617
|
-
async applyChangeAndReturnEvent(transaction, change, transactionCache
|
|
25453
|
+
async applyChangeAndReturnEvent(transaction, change, transactionCache) {
|
|
25618
25454
|
if (change.type === "set") {
|
|
25619
|
-
let existing;
|
|
25620
|
-
if (options?.captureRows) {
|
|
25621
|
-
existing = await this.readExisting(transaction, change.data._id, transactionCache);
|
|
25622
|
-
}
|
|
25623
25455
|
await transaction.set(this.storeName, change.data);
|
|
25624
25456
|
const item = this.deserialize ? this.deserialize(change.data) : change.data;
|
|
25625
25457
|
if (transactionCache) {
|
|
@@ -25632,16 +25464,10 @@ var init_dist2 = __esm(() => {
|
|
|
25632
25464
|
type: "set",
|
|
25633
25465
|
item: change.data,
|
|
25634
25466
|
id: change.data._id
|
|
25635
|
-
}
|
|
25636
|
-
oldRow: existing ?? null,
|
|
25637
|
-
newRow: change.data
|
|
25467
|
+
}
|
|
25638
25468
|
};
|
|
25639
25469
|
}
|
|
25640
25470
|
if (change.type === "delete") {
|
|
25641
|
-
let existing;
|
|
25642
|
-
if (options?.captureRows) {
|
|
25643
|
-
existing = await this.readExisting(transaction, change.id, transactionCache);
|
|
25644
|
-
}
|
|
25645
25471
|
await transaction.remove(this.storeName, change.id);
|
|
25646
25472
|
if (transactionCache) {
|
|
25647
25473
|
transactionCache.delete(`${this.storeName}:${change.id}`);
|
|
@@ -25653,9 +25479,7 @@ var init_dist2 = __esm(() => {
|
|
|
25653
25479
|
type: "delete",
|
|
25654
25480
|
item: null,
|
|
25655
25481
|
id: change.id
|
|
25656
|
-
}
|
|
25657
|
-
oldRow: existing ?? null,
|
|
25658
|
-
newRow: null
|
|
25482
|
+
}
|
|
25659
25483
|
};
|
|
25660
25484
|
}
|
|
25661
25485
|
if (change.type === "modify") {
|
|
@@ -25673,9 +25497,7 @@ var init_dist2 = __esm(() => {
|
|
|
25673
25497
|
type: "set",
|
|
25674
25498
|
item,
|
|
25675
25499
|
id: change.id
|
|
25676
|
-
}
|
|
25677
|
-
oldRow: existing ?? null,
|
|
25678
|
-
newRow: updated
|
|
25500
|
+
}
|
|
25679
25501
|
};
|
|
25680
25502
|
}
|
|
25681
25503
|
if (change.type === "mutate") {
|
|
@@ -25693,9 +25515,7 @@ var init_dist2 = __esm(() => {
|
|
|
25693
25515
|
type: "set",
|
|
25694
25516
|
item,
|
|
25695
25517
|
id: change.id
|
|
25696
|
-
}
|
|
25697
|
-
oldRow: existing ?? null,
|
|
25698
|
-
newRow: updated
|
|
25518
|
+
}
|
|
25699
25519
|
};
|
|
25700
25520
|
}
|
|
25701
25521
|
throw new Error("Unknown change type");
|
|
@@ -25772,22 +25592,17 @@ var init_dist2 = __esm(() => {
|
|
|
25772
25592
|
applySerializedChanges(changes) {
|
|
25773
25593
|
return Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applySerializedChanges(changes2)));
|
|
25774
25594
|
}
|
|
25775
|
-
async commitChanges(changes
|
|
25595
|
+
async commitChanges(changes) {
|
|
25776
25596
|
const transaction = await this.getReadWriteTransaction();
|
|
25777
25597
|
const transactionCache = new Map;
|
|
25778
25598
|
const eventsByStore = new Map;
|
|
25779
|
-
const committed = [];
|
|
25780
25599
|
for (const { store, changes: storeChanges } of changes) {
|
|
25781
25600
|
const storeState = this.getStore(store);
|
|
25782
25601
|
const storeEvents = [];
|
|
25783
|
-
const capture = options?.captureRowsFor?.has(store) ?? false;
|
|
25784
25602
|
for (const change of storeChanges) {
|
|
25785
|
-
const { event: event3
|
|
25603
|
+
const { event: event3 } = await storeState.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
25786
25604
|
if (event3)
|
|
25787
25605
|
storeEvents.push(event3);
|
|
25788
|
-
if (capture) {
|
|
25789
|
-
committed.push({ store, id: event3.id, oldRow, newRow });
|
|
25790
|
-
}
|
|
25791
25606
|
}
|
|
25792
25607
|
if (storeEvents.length > 0) {
|
|
25793
25608
|
eventsByStore.set(store, storeEvents);
|
|
@@ -25798,7 +25613,6 @@ var init_dist2 = __esm(() => {
|
|
|
25798
25613
|
const storeState = this.getStore(store);
|
|
25799
25614
|
storeState.notifyListenersPublic(events);
|
|
25800
25615
|
}
|
|
25801
|
-
return committed;
|
|
25802
25616
|
}
|
|
25803
25617
|
fork() {
|
|
25804
25618
|
return new ForkedDataStorage2(this);
|
|
@@ -34582,8 +34396,8 @@ ${colors3.yellow}Type declaration errors:${colors3.reset}`);
|
|
|
34582
34396
|
}
|
|
34583
34397
|
|
|
34584
34398
|
// src/platform/shared.ts
|
|
34585
|
-
import { copyFileSync, existsSync as existsSync10, mkdirSync as mkdirSync9, readdirSync as
|
|
34586
|
-
import { dirname as dirname8, join as
|
|
34399
|
+
import { copyFileSync, existsSync as existsSync10, mkdirSync as mkdirSync9, readdirSync as readdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
34400
|
+
import { dirname as dirname8, join as join12 } from "path";
|
|
34587
34401
|
|
|
34588
34402
|
// src/builder/module-builder.ts
|
|
34589
34403
|
import { execSync } from "child_process";
|
|
@@ -35378,7 +35192,8 @@ writeFileSync(out, JSON.stringify(result, null, 2) + "\\n");
|
|
|
35378
35192
|
`.trim();
|
|
35379
35193
|
|
|
35380
35194
|
// src/builder/chunk-planner.ts
|
|
35381
|
-
import {
|
|
35195
|
+
import { readFileSync as readFileSync9, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
|
|
35196
|
+
import { basename as basename3, join as join10 } from "path";
|
|
35382
35197
|
var PUBLIC_CHUNK = "public";
|
|
35383
35198
|
function planChunks(packages, accessMap) {
|
|
35384
35199
|
const assignments = new Map;
|
|
@@ -35410,6 +35225,53 @@ function planChunks(packages, accessMap) {
|
|
|
35410
35225
|
});
|
|
35411
35226
|
return { assignments, groups, chunks };
|
|
35412
35227
|
}
|
|
35228
|
+
var MODULE_CALL = /\bmodule\(\s*["'`]([a-zA-Z0-9_-]+)["'`]/g;
|
|
35229
|
+
function collectModuleNames(dir, acc) {
|
|
35230
|
+
let entries;
|
|
35231
|
+
try {
|
|
35232
|
+
entries = readdirSync5(dir);
|
|
35233
|
+
} catch {
|
|
35234
|
+
return;
|
|
35235
|
+
}
|
|
35236
|
+
for (const e of entries) {
|
|
35237
|
+
if (e === "node_modules" || e === "dist")
|
|
35238
|
+
continue;
|
|
35239
|
+
const full = join10(dir, e);
|
|
35240
|
+
let isDir = false;
|
|
35241
|
+
try {
|
|
35242
|
+
isDir = statSync2(full).isDirectory();
|
|
35243
|
+
} catch {
|
|
35244
|
+
continue;
|
|
35245
|
+
}
|
|
35246
|
+
if (isDir) {
|
|
35247
|
+
collectModuleNames(full, acc);
|
|
35248
|
+
} else if (e.endsWith(".ts") || e.endsWith(".tsx")) {
|
|
35249
|
+
const src = readFileSync9(full, "utf-8");
|
|
35250
|
+
MODULE_CALL.lastIndex = 0;
|
|
35251
|
+
let m;
|
|
35252
|
+
while (m = MODULE_CALL.exec(src))
|
|
35253
|
+
acc.add(m[1]);
|
|
35254
|
+
}
|
|
35255
|
+
}
|
|
35256
|
+
}
|
|
35257
|
+
function assertOneModulePerPackage(packages) {
|
|
35258
|
+
const offenders = [];
|
|
35259
|
+
for (const pkg of packages) {
|
|
35260
|
+
const names = new Set;
|
|
35261
|
+
collectModuleNames(join10(pkg.path, "src"), names);
|
|
35262
|
+
if (names.size > 1) {
|
|
35263
|
+
offenders.push({ pkg: pkg.name, modules: [...names].sort() });
|
|
35264
|
+
}
|
|
35265
|
+
}
|
|
35266
|
+
if (offenders.length === 0)
|
|
35267
|
+
return;
|
|
35268
|
+
const detail = offenders.map((o) => ` \u2022 ${o.pkg} declares ${o.modules.length}: ${o.modules.join(", ")}`).join(`
|
|
35269
|
+
`);
|
|
35270
|
+
throw new Error(`Arc build: a workspace package must declare at most ONE module().
|
|
35271
|
+
` + `Chunk grouping is per-package \u2014 a second module() silently inherits the ` + `first module's token protection and chunk, so e.g. a public onboarding ` + `page sharing a package with a workspaceToken-gated module becomes ` + `unreachable for users without that token.
|
|
35272
|
+
${detail}
|
|
35273
|
+
` + `Fix: move each extra module() into its own workspace package ` + `(declare its own protectedBy there).`);
|
|
35274
|
+
}
|
|
35413
35275
|
function moduleNameOf(pkgName) {
|
|
35414
35276
|
return pkgName.includes("/") ? pkgName.split("/").pop() : pkgName;
|
|
35415
35277
|
}
|
|
@@ -35417,17 +35279,19 @@ function resolveChunk(moduleName, access) {
|
|
|
35417
35279
|
if (!access || access.rules.length === 0)
|
|
35418
35280
|
return PUBLIC_CHUNK;
|
|
35419
35281
|
const tokenNames = new Set(access.rules.map((r) => r.token.name));
|
|
35420
|
-
if (tokenNames.size
|
|
35421
|
-
|
|
35282
|
+
if (tokenNames.size > 1) {
|
|
35283
|
+
const list = [...tokenNames].sort().join(", ");
|
|
35284
|
+
throw new Error(`Module "${moduleName}" has access rules for multiple tokens [${list}]. ` + `Multi-token modules are not supported \u2014 split the module or unify on a single token type.`);
|
|
35422
35285
|
}
|
|
35423
|
-
const
|
|
35424
|
-
|
|
35286
|
+
const tokenName = [...tokenNames][0];
|
|
35287
|
+
const hasCheck = access.rules.some((r) => r.hasCheck);
|
|
35288
|
+
return hasCheck ? `${tokenName}__${moduleName}` : tokenName;
|
|
35425
35289
|
}
|
|
35426
35290
|
|
|
35427
35291
|
// src/builder/dependency-collector.ts
|
|
35428
35292
|
import { createHash } from "crypto";
|
|
35429
|
-
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as
|
|
35430
|
-
import { basename as basename4, dirname as dirname7, join as
|
|
35293
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
|
|
35294
|
+
import { basename as basename4, dirname as dirname7, join as join11 } from "path";
|
|
35431
35295
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
35432
35296
|
function collectFrameworkDeps(arcDir, rootDir, packages, sharedDeps = []) {
|
|
35433
35297
|
mkdirSync8(arcDir, { recursive: true });
|
|
@@ -35438,7 +35302,7 @@ function collectFrameworkDeps(arcDir, rootDir, packages, sharedDeps = []) {
|
|
|
35438
35302
|
try {
|
|
35439
35303
|
const cliDir = dirname7(fileURLToPath6(import.meta.url));
|
|
35440
35304
|
const arcOtelPkgPath = Bun.resolveSync("@arcote.tech/arc-otel/package.json", cliDir);
|
|
35441
|
-
const arcOtelPkg = JSON.parse(
|
|
35305
|
+
const arcOtelPkg = JSON.parse(readFileSync10(arcOtelPkgPath, "utf-8"));
|
|
35442
35306
|
for (const [name, spec] of Object.entries(arcOtelPkg.dependencies ?? {})) {
|
|
35443
35307
|
if (name.startsWith("@opentelemetry/")) {
|
|
35444
35308
|
versions[name] = spec;
|
|
@@ -35449,10 +35313,10 @@ function collectFrameworkDeps(arcDir, rootDir, packages, sharedDeps = []) {
|
|
|
35449
35313
|
console.warn(`[arc-otel] could not resolve @arcote.tech/arc-otel \u2014 image will run without telemetry deps: ${e.message}`);
|
|
35450
35314
|
}
|
|
35451
35315
|
let rootArc;
|
|
35452
|
-
const rootPkgPath =
|
|
35316
|
+
const rootPkgPath = join11(rootDir, "package.json");
|
|
35453
35317
|
if (existsSync9(rootPkgPath)) {
|
|
35454
35318
|
try {
|
|
35455
|
-
const rootPkg = JSON.parse(
|
|
35319
|
+
const rootPkg = JSON.parse(readFileSync10(rootPkgPath, "utf-8"));
|
|
35456
35320
|
if (rootPkg.arc && typeof rootPkg.arc === "object")
|
|
35457
35321
|
rootArc = rootPkg.arc;
|
|
35458
35322
|
} catch {}
|
|
@@ -35464,11 +35328,11 @@ function collectFrameworkDeps(arcDir, rootDir, packages, sharedDeps = []) {
|
|
|
35464
35328
|
dependencies: versions,
|
|
35465
35329
|
...rootArc ? { arc: rootArc } : {}
|
|
35466
35330
|
};
|
|
35467
|
-
const manifestPath =
|
|
35331
|
+
const manifestPath = join11(arcDir, "package.json");
|
|
35468
35332
|
writeFileSync8(manifestPath, JSON.stringify(manifest, null, 2) + `
|
|
35469
35333
|
`);
|
|
35470
|
-
const hash = sha256Hex2(
|
|
35471
|
-
writeFileSync8(
|
|
35334
|
+
const hash = sha256Hex2(readFileSync10(manifestPath));
|
|
35335
|
+
writeFileSync8(join11(arcDir, ".deps-hash"), hash + `
|
|
35472
35336
|
`);
|
|
35473
35337
|
return { hash, manifestPath };
|
|
35474
35338
|
}
|
|
@@ -35476,7 +35340,7 @@ function sha256Hex2(bytes) {
|
|
|
35476
35340
|
return createHash("sha256").update(bytes).digest("hex");
|
|
35477
35341
|
}
|
|
35478
35342
|
function resolveFrameworkVersions(rootDir, packages) {
|
|
35479
|
-
const rootPkg = JSON.parse(
|
|
35343
|
+
const rootPkg = JSON.parse(readFileSync10(join11(rootDir, "package.json"), "utf-8"));
|
|
35480
35344
|
const rootDeps = rootPkg.dependencies ?? {};
|
|
35481
35345
|
const rootDevDeps = rootPkg.devDependencies ?? {};
|
|
35482
35346
|
const required = new Set(FRAMEWORK_PEERS);
|
|
@@ -35535,9 +35399,9 @@ function resolveWorkspace() {
|
|
|
35535
35399
|
process.exit(1);
|
|
35536
35400
|
}
|
|
35537
35401
|
const rootDir = dirname8(packageJsonPath);
|
|
35538
|
-
const rootPkg = JSON.parse(
|
|
35402
|
+
const rootPkg = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
|
|
35539
35403
|
const appName = rootPkg.name ?? "Arc App";
|
|
35540
|
-
const arcDir =
|
|
35404
|
+
const arcDir = join12(rootDir, ".arc", "platform");
|
|
35541
35405
|
log2("Scanning workspaces...");
|
|
35542
35406
|
const packages = discoverPackages(rootDir);
|
|
35543
35407
|
if (packages.length > 0) {
|
|
@@ -35547,10 +35411,10 @@ function resolveWorkspace() {
|
|
|
35547
35411
|
}
|
|
35548
35412
|
let manifest;
|
|
35549
35413
|
for (const name of ["manifest.json", "manifest.webmanifest"]) {
|
|
35550
|
-
const manifestPath =
|
|
35414
|
+
const manifestPath = join12(rootDir, name);
|
|
35551
35415
|
if (existsSync10(manifestPath)) {
|
|
35552
35416
|
try {
|
|
35553
|
-
const data = JSON.parse(
|
|
35417
|
+
const data = JSON.parse(readFileSync11(manifestPath, "utf-8"));
|
|
35554
35418
|
const icons = data.icons;
|
|
35555
35419
|
manifest = {
|
|
35556
35420
|
path: manifestPath,
|
|
@@ -35569,9 +35433,9 @@ function resolveWorkspace() {
|
|
|
35569
35433
|
rootPkg,
|
|
35570
35434
|
appName,
|
|
35571
35435
|
arcDir,
|
|
35572
|
-
browserDir:
|
|
35573
|
-
assetsDir:
|
|
35574
|
-
publicDir:
|
|
35436
|
+
browserDir: join12(arcDir, "browser"),
|
|
35437
|
+
assetsDir: join12(arcDir, "assets"),
|
|
35438
|
+
publicDir: join12(rootDir, "public"),
|
|
35575
35439
|
packages,
|
|
35576
35440
|
manifest
|
|
35577
35441
|
};
|
|
@@ -35581,11 +35445,12 @@ async function buildAll(ws, opts = {}) {
|
|
|
35581
35445
|
const noCache = opts.noCache ?? false;
|
|
35582
35446
|
const themePath = ws.rootPkg.arc?.theme;
|
|
35583
35447
|
log2(`Building (concurrency parallel${noCache ? ", no-cache" : ""})...`);
|
|
35448
|
+
assertOneModulePerPackage(ws.packages);
|
|
35584
35449
|
await buildContextPackages(ws.rootDir, ws.packages, cache, noCache);
|
|
35585
35450
|
copyContextServerBundles(ws);
|
|
35586
35451
|
const accessMap = await extractAccessMap(ws.rootDir, ws.packages);
|
|
35587
35452
|
mkdirSync9(ws.arcDir, { recursive: true });
|
|
35588
|
-
writeFileSync9(
|
|
35453
|
+
writeFileSync9(join12(ws.arcDir, "access.json"), JSON.stringify(accessMap, null, 2) + `
|
|
35589
35454
|
`);
|
|
35590
35455
|
const plan = planChunks(ws.packages, accessMap);
|
|
35591
35456
|
ok(`Chunks: ${plan.chunks.map((c) => `${c}(${plan.groups.get(c)?.length ?? 0})`).join(", ")}`);
|
|
@@ -35601,7 +35466,7 @@ async function buildAll(ws, opts = {}) {
|
|
|
35601
35466
|
collectFrameworkDeps(ws.arcDir, ws.rootDir, ws.packages);
|
|
35602
35467
|
saveBuildCache(ws.arcDir, cache);
|
|
35603
35468
|
const finalManifest = assembleManifest(ws, browserResult, cache);
|
|
35604
|
-
writeFileSync9(
|
|
35469
|
+
writeFileSync9(join12(ws.arcDir, "manifest.json"), JSON.stringify(finalManifest, null, 2));
|
|
35605
35470
|
return finalManifest;
|
|
35606
35471
|
}
|
|
35607
35472
|
function assembleManifest(ws, browser, cache) {
|
|
@@ -35615,40 +35480,40 @@ function assembleManifest(ws, browser, cache) {
|
|
|
35615
35480
|
};
|
|
35616
35481
|
}
|
|
35617
35482
|
function copyContextServerBundles(ws) {
|
|
35618
|
-
const outDir =
|
|
35483
|
+
const outDir = join12(ws.arcDir, "server");
|
|
35619
35484
|
mkdirSync9(outDir, { recursive: true });
|
|
35620
35485
|
for (const pkg of ws.packages) {
|
|
35621
35486
|
if (!isContextPackage(pkg.packageJson))
|
|
35622
35487
|
continue;
|
|
35623
|
-
const src =
|
|
35488
|
+
const src = join12(pkg.path, "dist", "server", "main", "index.js");
|
|
35624
35489
|
if (!existsSync10(src)) {
|
|
35625
35490
|
err(`Server bundle missing for ${pkg.name}: ${src}`);
|
|
35626
35491
|
continue;
|
|
35627
35492
|
}
|
|
35628
35493
|
const safeName = pkg.path.split("/").pop();
|
|
35629
|
-
const dst =
|
|
35494
|
+
const dst = join12(outDir, `${safeName}.js`);
|
|
35630
35495
|
copyFileSync(src, dst);
|
|
35631
35496
|
}
|
|
35632
35497
|
}
|
|
35633
35498
|
function resolveAssetSource(from, pkgDir, rootDir) {
|
|
35634
35499
|
if (from.startsWith("./") || from.startsWith("../")) {
|
|
35635
|
-
const resolved =
|
|
35500
|
+
const resolved = join12(pkgDir, from);
|
|
35636
35501
|
return existsSync10(resolved) ? resolved : null;
|
|
35637
35502
|
}
|
|
35638
35503
|
const candidates = [
|
|
35639
|
-
|
|
35640
|
-
|
|
35504
|
+
join12(rootDir, "node_modules", from),
|
|
35505
|
+
join12(pkgDir, "node_modules", from)
|
|
35641
35506
|
];
|
|
35642
35507
|
for (const c of candidates) {
|
|
35643
35508
|
if (existsSync10(c))
|
|
35644
35509
|
return c;
|
|
35645
35510
|
}
|
|
35646
|
-
const bunCacheDir =
|
|
35511
|
+
const bunCacheDir = join12(rootDir, "node_modules", ".bun");
|
|
35647
35512
|
if (existsSync10(bunCacheDir)) {
|
|
35648
|
-
for (const entry of
|
|
35513
|
+
for (const entry of readdirSync6(bunCacheDir, { withFileTypes: true })) {
|
|
35649
35514
|
if (!entry.isDirectory())
|
|
35650
35515
|
continue;
|
|
35651
|
-
const candidate =
|
|
35516
|
+
const candidate = join12(bunCacheDir, entry.name, "node_modules", from);
|
|
35652
35517
|
if (existsSync10(candidate))
|
|
35653
35518
|
return candidate;
|
|
35654
35519
|
}
|
|
@@ -35656,11 +35521,11 @@ function resolveAssetSource(from, pkgDir, rootDir) {
|
|
|
35656
35521
|
return null;
|
|
35657
35522
|
}
|
|
35658
35523
|
function readBrowserAssets(pkgDir) {
|
|
35659
|
-
const pkgJsonPath =
|
|
35524
|
+
const pkgJsonPath = join12(pkgDir, "package.json");
|
|
35660
35525
|
if (!existsSync10(pkgJsonPath))
|
|
35661
35526
|
return [];
|
|
35662
35527
|
try {
|
|
35663
|
-
const pkg = JSON.parse(
|
|
35528
|
+
const pkg = JSON.parse(readFileSync11(pkgJsonPath, "utf-8"));
|
|
35664
35529
|
const assets = pkg.arc?.browserAssets;
|
|
35665
35530
|
if (!Array.isArray(assets))
|
|
35666
35531
|
return [];
|
|
@@ -35670,14 +35535,14 @@ function readBrowserAssets(pkgDir) {
|
|
|
35670
35535
|
}
|
|
35671
35536
|
}
|
|
35672
35537
|
function discoverBrowserAssets(ws) {
|
|
35673
|
-
const arcDir =
|
|
35538
|
+
const arcDir = join12(ws.rootDir, "node_modules", "@arcote.tech");
|
|
35674
35539
|
if (!existsSync10(arcDir))
|
|
35675
35540
|
return [];
|
|
35676
35541
|
const out = [];
|
|
35677
|
-
for (const entry of
|
|
35542
|
+
for (const entry of readdirSync6(arcDir, { withFileTypes: true })) {
|
|
35678
35543
|
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
35679
35544
|
continue;
|
|
35680
|
-
const pkgDir =
|
|
35545
|
+
const pkgDir = join12(arcDir, entry.name);
|
|
35681
35546
|
const assets = readBrowserAssets(pkgDir);
|
|
35682
35547
|
for (const asset of assets) {
|
|
35683
35548
|
const src = resolveAssetSource(asset.from, pkgDir, ws.rootDir);
|
|
@@ -35702,7 +35567,7 @@ async function copyBrowserAssets(ws, cache, noCache) {
|
|
|
35702
35567
|
to: a.to,
|
|
35703
35568
|
mtime: mtimeOf(a.src)
|
|
35704
35569
|
})));
|
|
35705
|
-
const requiredOutputs = assets.map((a) =>
|
|
35570
|
+
const requiredOutputs = assets.map((a) => join12(ws.assetsDir, a.to));
|
|
35706
35571
|
if (!noCache && isCacheHit(cache, unitId, inputHash, requiredOutputs)) {
|
|
35707
35572
|
console.log(` \u2713 cached: browser-assets (${assets.length})`);
|
|
35708
35573
|
return;
|
|
@@ -35710,10 +35575,10 @@ async function copyBrowserAssets(ws, cache, noCache) {
|
|
|
35710
35575
|
console.log(` building: browser-assets (${assets.length})`);
|
|
35711
35576
|
const outputHashes = {};
|
|
35712
35577
|
for (const asset of assets) {
|
|
35713
|
-
const dest =
|
|
35578
|
+
const dest = join12(ws.assetsDir, asset.to);
|
|
35714
35579
|
mkdirSync9(dirname8(dest), { recursive: true });
|
|
35715
35580
|
copyFileSync(asset.src, dest);
|
|
35716
|
-
outputHashes[asset.to] = sha256Hex(
|
|
35581
|
+
outputHashes[asset.to] = sha256Hex(readFileSync11(dest));
|
|
35717
35582
|
}
|
|
35718
35583
|
updateCache(cache, unitId, inputHash, { outputHashes });
|
|
35719
35584
|
}
|
|
@@ -35721,15 +35586,15 @@ async function loadServerContext(ws) {
|
|
|
35721
35586
|
globalThis.ONLY_SERVER = true;
|
|
35722
35587
|
globalThis.ONLY_BROWSER = false;
|
|
35723
35588
|
globalThis.ONLY_CLIENT = false;
|
|
35724
|
-
const platformDir =
|
|
35725
|
-
const platformPkg = JSON.parse(
|
|
35726
|
-
const platformEntry =
|
|
35589
|
+
const platformDir = join12(process.cwd(), "node_modules", "@arcote.tech", "platform");
|
|
35590
|
+
const platformPkg = JSON.parse(readFileSync11(join12(platformDir, "package.json"), "utf-8"));
|
|
35591
|
+
const platformEntry = join12(platformDir, platformPkg.main ?? "src/index.ts");
|
|
35727
35592
|
await import(platformEntry);
|
|
35728
|
-
const serverDir =
|
|
35729
|
-
const bundles = existsSync10(serverDir) ?
|
|
35593
|
+
const serverDir = join12(ws.arcDir, "server");
|
|
35594
|
+
const bundles = existsSync10(serverDir) ? readdirSync6(serverDir).filter((f) => f.endsWith(".js")) : [];
|
|
35730
35595
|
if (bundles.length > 0) {
|
|
35731
35596
|
for (const file of bundles) {
|
|
35732
|
-
const bundlePath =
|
|
35597
|
+
const bundlePath = join12(serverDir, file);
|
|
35733
35598
|
try {
|
|
35734
35599
|
await import(bundlePath);
|
|
35735
35600
|
} catch (e) {
|
|
@@ -35739,7 +35604,7 @@ async function loadServerContext(ws) {
|
|
|
35739
35604
|
} else if (ws.packages.length > 0) {
|
|
35740
35605
|
const ctxPackages = ws.packages.filter((p) => isContextPackage(p.packageJson));
|
|
35741
35606
|
for (const ctx of ctxPackages) {
|
|
35742
|
-
const serverDist =
|
|
35607
|
+
const serverDist = join12(ctx.path, "dist", "server", "main", "index.js");
|
|
35743
35608
|
if (!existsSync10(serverDist)) {
|
|
35744
35609
|
err(`Context server dist not found: ${serverDist}`);
|
|
35745
35610
|
continue;
|
|
@@ -35769,21 +35634,21 @@ async function platformBuild(opts = {}) {
|
|
|
35769
35634
|
}
|
|
35770
35635
|
|
|
35771
35636
|
// src/commands/platform-deploy.ts
|
|
35772
|
-
import { existsSync as existsSync17, readFileSync as
|
|
35773
|
-
import { dirname as dirname11, join as
|
|
35637
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15 } from "fs";
|
|
35638
|
+
import { dirname as dirname11, join as join20 } from "path";
|
|
35774
35639
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
35775
35640
|
|
|
35776
35641
|
// src/deploy/bootstrap.ts
|
|
35777
35642
|
var {spawn: spawn4 } = globalThis.Bun;
|
|
35778
35643
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync13 } from "fs";
|
|
35779
35644
|
import { tmpdir as tmpdir2 } from "os";
|
|
35780
|
-
import { dirname as dirname9, join as
|
|
35645
|
+
import { dirname as dirname9, join as join18 } from "path";
|
|
35781
35646
|
|
|
35782
35647
|
// src/deploy/ansible.ts
|
|
35783
35648
|
import { spawn as nodeSpawn } from "child_process";
|
|
35784
35649
|
import { existsSync as existsSync11, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
35785
35650
|
import { homedir, tmpdir } from "os";
|
|
35786
|
-
import { join as
|
|
35651
|
+
import { join as join13 } from "path";
|
|
35787
35652
|
|
|
35788
35653
|
// src/deploy/assets.ts
|
|
35789
35654
|
var TERRAFORM_MAIN_TF = `terraform {
|
|
@@ -36057,28 +35922,28 @@ var ASSETS = {
|
|
|
36057
35922
|
};
|
|
36058
35923
|
async function materializeAssets(targetDir, files) {
|
|
36059
35924
|
const { mkdirSync: mkdirSync10, writeFileSync: writeFileSync10 } = await import("fs");
|
|
36060
|
-
const { join:
|
|
35925
|
+
const { join: join13 } = await import("path");
|
|
36061
35926
|
mkdirSync10(targetDir, { recursive: true });
|
|
36062
35927
|
for (const [name, content] of Object.entries(files)) {
|
|
36063
|
-
writeFileSync10(
|
|
35928
|
+
writeFileSync10(join13(targetDir, name), content);
|
|
36064
35929
|
}
|
|
36065
35930
|
}
|
|
36066
35931
|
|
|
36067
35932
|
// src/deploy/ansible.ts
|
|
36068
35933
|
function pickSshKeyForAnsible(configured) {
|
|
36069
35934
|
if (configured) {
|
|
36070
|
-
const expanded = configured.startsWith("~") ?
|
|
35935
|
+
const expanded = configured.startsWith("~") ? join13(homedir(), configured.slice(1)) : configured;
|
|
36071
35936
|
return existsSync11(expanded) ? expanded : null;
|
|
36072
35937
|
}
|
|
36073
35938
|
for (const name of ["id_ed25519", "id_ecdsa", "id_rsa"]) {
|
|
36074
|
-
const path4 =
|
|
35939
|
+
const path4 = join13(homedir(), ".ssh", name);
|
|
36075
35940
|
if (existsSync11(path4))
|
|
36076
35941
|
return path4;
|
|
36077
35942
|
}
|
|
36078
35943
|
return null;
|
|
36079
35944
|
}
|
|
36080
35945
|
async function runAnsible(inputs) {
|
|
36081
|
-
const workDir =
|
|
35946
|
+
const workDir = join13(tmpdir(), "arc-deploy", `ansible-${Date.now()}`);
|
|
36082
35947
|
mkdirSync10(workDir, { recursive: true });
|
|
36083
35948
|
await materializeAssets(workDir, ASSETS.ansible);
|
|
36084
35949
|
const user = inputs.asRoot ? "root" : inputs.target.user;
|
|
@@ -36095,7 +35960,7 @@ async function runAnsible(inputs) {
|
|
|
36095
35960
|
""
|
|
36096
35961
|
].join(`
|
|
36097
35962
|
`);
|
|
36098
|
-
writeFileSync10(
|
|
35963
|
+
writeFileSync10(join13(workDir, "inventory.ini"), inventory);
|
|
36099
35964
|
const extraVarsJson = JSON.stringify({
|
|
36100
35965
|
username: inputs.target.user,
|
|
36101
35966
|
ssh_port: port,
|
|
@@ -37143,10 +37008,10 @@ import { spawn as nodeSpawn2 } from "child_process";
|
|
|
37143
37008
|
import { createHash as createHash2 } from "crypto";
|
|
37144
37009
|
import { existsSync as existsSync12, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
|
|
37145
37010
|
import { homedir as homedir2 } from "os";
|
|
37146
|
-
import { join as
|
|
37011
|
+
import { join as join14 } from "path";
|
|
37147
37012
|
async function runTerraform(inputs) {
|
|
37148
37013
|
const wsHash = createHash2("sha256").update(inputs.workspaceDir).digest("hex").slice(0, 16);
|
|
37149
|
-
const workDir =
|
|
37014
|
+
const workDir = join14(homedir2(), ".arc-deploy", wsHash, "tf");
|
|
37150
37015
|
mkdirSync11(workDir, { recursive: true });
|
|
37151
37016
|
await materializeAssets(workDir, ASSETS.terraform);
|
|
37152
37017
|
const sshPubKey = inputs.tf.sshPublicKey ?? expandHome("~/.ssh/id_ed25519.pub");
|
|
@@ -37163,7 +37028,7 @@ async function runTerraform(inputs) {
|
|
|
37163
37028
|
].join(`
|
|
37164
37029
|
`) + `
|
|
37165
37030
|
`;
|
|
37166
|
-
writeFileSync11(
|
|
37031
|
+
writeFileSync11(join14(workDir, "terraform.tfvars"), tfvars);
|
|
37167
37032
|
await runTf(workDir, ["init", "-input=false", "-no-color"]);
|
|
37168
37033
|
await runTf(workDir, [
|
|
37169
37034
|
"apply",
|
|
@@ -37221,20 +37086,20 @@ function expandHome(p) {
|
|
|
37221
37086
|
}
|
|
37222
37087
|
|
|
37223
37088
|
// src/deploy/config.ts
|
|
37224
|
-
import { existsSync as existsSync14, readFileSync as
|
|
37225
|
-
import { join as
|
|
37089
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync12 } from "fs";
|
|
37090
|
+
import { join as join16 } from "path";
|
|
37226
37091
|
|
|
37227
37092
|
// src/deploy/env-file.ts
|
|
37228
|
-
import { appendFileSync, existsSync as existsSync13, readFileSync as
|
|
37229
|
-
import { join as
|
|
37093
|
+
import { appendFileSync, existsSync as existsSync13, readFileSync as readFileSync12 } from "fs";
|
|
37094
|
+
import { join as join15 } from "path";
|
|
37230
37095
|
function loadDeployEnvFiles(rootDir, envNames) {
|
|
37231
|
-
const globalsPath =
|
|
37232
|
-
const globals = existsSync13(globalsPath) ? parseEnvFile(
|
|
37096
|
+
const globalsPath = join15(rootDir, "deploy.arc.env");
|
|
37097
|
+
const globals = existsSync13(globalsPath) ? parseEnvFile(readFileSync12(globalsPath, "utf-8"), globalsPath) : {};
|
|
37233
37098
|
const perEnv = {};
|
|
37234
37099
|
for (const name of envNames) {
|
|
37235
|
-
const envPath =
|
|
37100
|
+
const envPath = join15(rootDir, `deploy.arc.${name}.env`);
|
|
37236
37101
|
if (existsSync13(envPath)) {
|
|
37237
|
-
perEnv[name] = parseEnvFile(
|
|
37102
|
+
perEnv[name] = parseEnvFile(readFileSync12(envPath, "utf-8"), envPath);
|
|
37238
37103
|
}
|
|
37239
37104
|
}
|
|
37240
37105
|
return { globals, perEnv };
|
|
@@ -37250,16 +37115,16 @@ function ensurePersistedSecret(rootDir, scope, key, generate) {
|
|
|
37250
37115
|
if (process.env[key])
|
|
37251
37116
|
return process.env[key];
|
|
37252
37117
|
const fileName = scope === "globals" ? "deploy.arc.env" : `deploy.arc.${scope}.env`;
|
|
37253
|
-
const path4 =
|
|
37118
|
+
const path4 = join15(rootDir, fileName);
|
|
37254
37119
|
if (existsSync13(path4)) {
|
|
37255
|
-
const existing = parseEnvFile(
|
|
37120
|
+
const existing = parseEnvFile(readFileSync12(path4, "utf-8"), path4);
|
|
37256
37121
|
if (existing[key]) {
|
|
37257
37122
|
process.env[key] = existing[key];
|
|
37258
37123
|
return existing[key];
|
|
37259
37124
|
}
|
|
37260
37125
|
}
|
|
37261
37126
|
const value = generate();
|
|
37262
|
-
const prefix = existsSync13(path4) && !
|
|
37127
|
+
const prefix = existsSync13(path4) && !readFileSync12(path4, "utf-8").endsWith(`
|
|
37263
37128
|
`) ? `
|
|
37264
37129
|
` : "";
|
|
37265
37130
|
appendFileSync(path4, `${prefix}${key}=${value}
|
|
@@ -37295,7 +37160,7 @@ function parseEnvFile(content, pathForErrors) {
|
|
|
37295
37160
|
// src/deploy/config.ts
|
|
37296
37161
|
var DEPLOY_CONFIG_FILE = "deploy.arc.json";
|
|
37297
37162
|
function deployConfigPath(rootDir) {
|
|
37298
|
-
return
|
|
37163
|
+
return join16(rootDir, DEPLOY_CONFIG_FILE);
|
|
37299
37164
|
}
|
|
37300
37165
|
function deployConfigExists(rootDir) {
|
|
37301
37166
|
return existsSync14(deployConfigPath(rootDir));
|
|
@@ -37305,7 +37170,7 @@ function loadDeployConfig(rootDir) {
|
|
|
37305
37170
|
if (!existsSync14(path4)) {
|
|
37306
37171
|
throw new Error(`Missing ${DEPLOY_CONFIG_FILE} at ${path4}`);
|
|
37307
37172
|
}
|
|
37308
|
-
const raw =
|
|
37173
|
+
const raw = readFileSync13(path4, "utf-8");
|
|
37309
37174
|
let parsed;
|
|
37310
37175
|
try {
|
|
37311
37176
|
parsed = JSON.parse(raw);
|
|
@@ -37328,7 +37193,7 @@ function loadDeployConfig(rootDir) {
|
|
|
37328
37193
|
}
|
|
37329
37194
|
function saveDeployConfig(rootDir, cfg) {
|
|
37330
37195
|
const path4 = deployConfigPath(rootDir);
|
|
37331
|
-
const raw = existsSync14(path4) ? JSON.parse(
|
|
37196
|
+
const raw = existsSync14(path4) ? JSON.parse(readFileSync13(path4, "utf-8")) : {};
|
|
37332
37197
|
raw.target = { ...raw.target, ...cfg.target };
|
|
37333
37198
|
writeFileSync12(path4, JSON.stringify(raw, null, 2) + `
|
|
37334
37199
|
`);
|
|
@@ -37541,14 +37406,14 @@ function cfgErr(path4, expected) {
|
|
|
37541
37406
|
var {spawn: spawn3 } = globalThis.Bun;
|
|
37542
37407
|
import { existsSync as existsSync15 } from "fs";
|
|
37543
37408
|
import { homedir as homedir3 } from "os";
|
|
37544
|
-
import { join as
|
|
37409
|
+
import { join as join17 } from "path";
|
|
37545
37410
|
function pickSshKey(target) {
|
|
37546
37411
|
if (target.sshKey) {
|
|
37547
|
-
const expanded = target.sshKey.startsWith("~") ?
|
|
37412
|
+
const expanded = target.sshKey.startsWith("~") ? join17(homedir3(), target.sshKey.slice(1)) : target.sshKey;
|
|
37548
37413
|
return existsSync15(expanded) ? expanded : null;
|
|
37549
37414
|
}
|
|
37550
37415
|
for (const name of ["id_ed25519", "id_ecdsa", "id_rsa"]) {
|
|
37551
|
-
const path4 =
|
|
37416
|
+
const path4 = join17(homedir3(), ".ssh", name);
|
|
37552
37417
|
if (existsSync15(path4))
|
|
37553
37418
|
return path4;
|
|
37554
37419
|
}
|
|
@@ -37784,7 +37649,7 @@ async function isRegistryRunning(cfg) {
|
|
|
37784
37649
|
}
|
|
37785
37650
|
async function upStack(inputs) {
|
|
37786
37651
|
const { cfg } = inputs;
|
|
37787
|
-
const workDir =
|
|
37652
|
+
const workDir = join18(tmpdir2(), "arc-deploy", `stack-${Date.now()}`);
|
|
37788
37653
|
mkdirSync12(workDir, { recursive: true });
|
|
37789
37654
|
await assertRegistryDnsResolves(cfg);
|
|
37790
37655
|
const password = process.env[cfg.registry.passwordEnv];
|
|
@@ -37792,9 +37657,9 @@ async function upStack(inputs) {
|
|
|
37792
37657
|
throw new Error(`Registry password env var ${cfg.registry.passwordEnv} is not set. ` + `Set it (e.g. \`export ${cfg.registry.passwordEnv}=...\`) before bootstrap.`);
|
|
37793
37658
|
}
|
|
37794
37659
|
const htpasswdLine = await generateHtpasswd(cfg.registry.username, password);
|
|
37795
|
-
writeFileSync13(
|
|
37796
|
-
writeFileSync13(
|
|
37797
|
-
writeFileSync13(
|
|
37660
|
+
writeFileSync13(join18(workDir, "htpasswd"), htpasswdLine);
|
|
37661
|
+
writeFileSync13(join18(workDir, "Caddyfile"), generateCaddyfile(cfg));
|
|
37662
|
+
writeFileSync13(join18(workDir, "docker-compose.yml"), generateCompose({ cfg }));
|
|
37798
37663
|
let observabilityFiles = null;
|
|
37799
37664
|
let observabilityHtpasswd = null;
|
|
37800
37665
|
if (cfg.observability?.enabled) {
|
|
@@ -37806,30 +37671,30 @@ async function upStack(inputs) {
|
|
|
37806
37671
|
}
|
|
37807
37672
|
observabilityHtpasswd = await generateCaddyBasicAuthLine("admin", adminPassword);
|
|
37808
37673
|
for (const [relPath, contents] of Object.entries(observabilityFiles)) {
|
|
37809
|
-
const fullPath =
|
|
37674
|
+
const fullPath = join18(workDir, relPath);
|
|
37810
37675
|
mkdirSync12(dirname9(fullPath), { recursive: true });
|
|
37811
37676
|
writeFileSync13(fullPath, contents);
|
|
37812
37677
|
}
|
|
37813
|
-
writeFileSync13(
|
|
37678
|
+
writeFileSync13(join18(workDir, "observability-htpasswd"), observabilityHtpasswd);
|
|
37814
37679
|
}
|
|
37815
37680
|
await assertExec(cfg.target, `sudo mkdir -p ${cfg.target.remoteDir} && sudo chown ${cfg.target.user}:${cfg.target.user} ${cfg.target.remoteDir}`);
|
|
37816
37681
|
for (const name of Object.keys(cfg.envs)) {
|
|
37817
37682
|
await assertExec(cfg.target, `mkdir -p ${cfg.target.remoteDir}/${name}`);
|
|
37818
37683
|
}
|
|
37819
37684
|
await assertExec(cfg.target, `mkdir -p ${cfg.target.remoteDir}/registry-auth`);
|
|
37820
|
-
await scpUpload(cfg.target,
|
|
37821
|
-
await scpUpload(cfg.target,
|
|
37822
|
-
await scpUpload(cfg.target,
|
|
37685
|
+
await scpUpload(cfg.target, join18(workDir, "Caddyfile"), `${cfg.target.remoteDir}/Caddyfile`);
|
|
37686
|
+
await scpUpload(cfg.target, join18(workDir, "docker-compose.yml"), `${cfg.target.remoteDir}/docker-compose.yml`);
|
|
37687
|
+
await scpUpload(cfg.target, join18(workDir, "htpasswd"), `${cfg.target.remoteDir}/registry-auth/htpasswd`);
|
|
37823
37688
|
if (observabilityFiles && observabilityHtpasswd) {
|
|
37824
37689
|
await assertExec(cfg.target, `mkdir -p ${cfg.target.remoteDir}/observability/grafana-dashboards`);
|
|
37825
37690
|
for (const relPath of Object.keys(observabilityFiles)) {
|
|
37826
|
-
const localDir = dirname9(
|
|
37691
|
+
const localDir = dirname9(join18(workDir, relPath));
|
|
37827
37692
|
mkdirSync12(localDir, { recursive: true });
|
|
37828
37693
|
}
|
|
37829
37694
|
for (const relPath of Object.keys(observabilityFiles)) {
|
|
37830
|
-
await scpUpload(cfg.target,
|
|
37695
|
+
await scpUpload(cfg.target, join18(workDir, relPath), `${cfg.target.remoteDir}/${relPath}`);
|
|
37831
37696
|
}
|
|
37832
|
-
await scpUpload(cfg.target,
|
|
37697
|
+
await scpUpload(cfg.target, join18(workDir, "observability-htpasswd"), `${cfg.target.remoteDir}/observability-htpasswd`);
|
|
37833
37698
|
}
|
|
37834
37699
|
await assertExec(cfg.target, `touch ${cfg.target.remoteDir}/.env`);
|
|
37835
37700
|
if (cfg.observability?.enabled) {
|
|
@@ -37997,12 +37862,12 @@ import {
|
|
|
37997
37862
|
copyFileSync as copyFileSync2,
|
|
37998
37863
|
existsSync as existsSync16,
|
|
37999
37864
|
mkdirSync as mkdirSync13,
|
|
38000
|
-
readFileSync as
|
|
37865
|
+
readFileSync as readFileSync14,
|
|
38001
37866
|
realpathSync as realpathSync2,
|
|
38002
37867
|
writeFileSync as writeFileSync14
|
|
38003
37868
|
} from "fs";
|
|
38004
37869
|
import { tmpdir as tmpdir3 } from "os";
|
|
38005
|
-
import { dirname as dirname10, join as
|
|
37870
|
+
import { dirname as dirname10, join as join19 } from "path";
|
|
38006
37871
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
38007
37872
|
|
|
38008
37873
|
// src/deploy/image-template.ts
|
|
@@ -38052,7 +37917,7 @@ function generateDockerfile(inputs) {
|
|
|
38052
37917
|
// src/deploy/image.ts
|
|
38053
37918
|
async function buildImage(ws, opts) {
|
|
38054
37919
|
await ensureDocker();
|
|
38055
|
-
const manifestPath =
|
|
37920
|
+
const manifestPath = join19(ws.arcDir, "manifest.json");
|
|
38056
37921
|
if (!existsSync16(manifestPath)) {
|
|
38057
37922
|
throw new Error(`No build manifest at ${manifestPath}. Run \`arc platform build\` first or omit --skip-build.`);
|
|
38058
37923
|
}
|
|
@@ -38063,9 +37928,9 @@ async function buildImage(ws, opts) {
|
|
|
38063
37928
|
const dockerfileInputs = collectDockerfileInputs(ws);
|
|
38064
37929
|
const dockerfile = generateDockerfile(dockerfileInputs);
|
|
38065
37930
|
const buildContextDir = ws.rootDir;
|
|
38066
|
-
const dockerfileDir =
|
|
37931
|
+
const dockerfileDir = join19(tmpdir3(), `arc-image-${Date.now()}`);
|
|
38067
37932
|
mkdirSync13(dockerfileDir, { recursive: true });
|
|
38068
|
-
const dockerfilePath =
|
|
37933
|
+
const dockerfilePath = join19(dockerfileDir, "Dockerfile");
|
|
38069
37934
|
writeFileSync14(dockerfilePath, dockerfile);
|
|
38070
37935
|
const buildArgs = [
|
|
38071
37936
|
"build",
|
|
@@ -38091,19 +37956,19 @@ async function buildImage(ws, opts) {
|
|
|
38091
37956
|
}
|
|
38092
37957
|
function embedCliBundle(ws) {
|
|
38093
37958
|
const source = locateCliBundle();
|
|
38094
|
-
const target =
|
|
37959
|
+
const target = join19(ws.arcDir, "host.js");
|
|
38095
37960
|
copyFileSync2(source, target);
|
|
38096
37961
|
}
|
|
38097
37962
|
function locateCliBundle() {
|
|
38098
37963
|
const here = fileURLToPath7(import.meta.url);
|
|
38099
37964
|
let cur = dirname10(here);
|
|
38100
37965
|
while (cur !== "/" && cur !== "") {
|
|
38101
|
-
const candidate =
|
|
37966
|
+
const candidate = join19(cur, "package.json");
|
|
38102
37967
|
if (existsSync16(candidate)) {
|
|
38103
37968
|
try {
|
|
38104
|
-
const pkg = JSON.parse(
|
|
37969
|
+
const pkg = JSON.parse(readFileSync14(candidate, "utf-8"));
|
|
38105
37970
|
if (pkg.name === "@arcote.tech/arc-cli") {
|
|
38106
|
-
const distIndex =
|
|
37971
|
+
const distIndex = join19(realpathSync2(cur), "dist", "index.js");
|
|
38107
37972
|
if (!existsSync16(distIndex)) {
|
|
38108
37973
|
throw new Error(`arc-cli bundle missing at ${distIndex}. Run \`bun run build\` in packages/cli/.`);
|
|
38109
37974
|
}
|
|
@@ -38136,17 +38001,17 @@ async function ensureDocker() {
|
|
|
38136
38001
|
}
|
|
38137
38002
|
}
|
|
38138
38003
|
function computeContentHash(manifestPath) {
|
|
38139
|
-
const raw = JSON.parse(
|
|
38004
|
+
const raw = JSON.parse(readFileSync14(manifestPath, "utf-8"));
|
|
38140
38005
|
delete raw.buildTime;
|
|
38141
38006
|
const canonical = JSON.stringify(raw);
|
|
38142
38007
|
return createHash3("sha256").update(canonical).digest("hex").slice(0, 12);
|
|
38143
38008
|
}
|
|
38144
38009
|
function collectDockerfileInputs(ws) {
|
|
38145
|
-
const hasPublicDir = existsSync16(
|
|
38146
|
-
const hasLocales = existsSync16(
|
|
38010
|
+
const hasPublicDir = existsSync16(join19(ws.rootDir, "public"));
|
|
38011
|
+
const hasLocales = existsSync16(join19(ws.rootDir, "locales"));
|
|
38147
38012
|
let manifestPath;
|
|
38148
38013
|
for (const name of ["manifest.webmanifest", "manifest.json"]) {
|
|
38149
|
-
if (existsSync16(
|
|
38014
|
+
if (existsSync16(join19(ws.rootDir, name))) {
|
|
38150
38015
|
manifestPath = name;
|
|
38151
38016
|
break;
|
|
38152
38017
|
}
|
|
@@ -38975,7 +38840,7 @@ async function platformDeploy(envArg, options = {}) {
|
|
|
38975
38840
|
err(`Unknown env "${envArg}". Known: ${Object.keys(cfg.envs).join(", ")}`);
|
|
38976
38841
|
process.exit(1);
|
|
38977
38842
|
})() : Object.keys(cfg.envs);
|
|
38978
|
-
const manifestPath =
|
|
38843
|
+
const manifestPath = join20(ws.arcDir, "manifest.json");
|
|
38979
38844
|
if (!options.imageTag) {
|
|
38980
38845
|
const needBuild = options.rebuild || !existsSync17(manifestPath);
|
|
38981
38846
|
if (needBuild && !options.skipBuild) {
|
|
@@ -39048,9 +38913,9 @@ function readCliVersion2() {
|
|
|
39048
38913
|
let cur = dirname11(fileURLToPath8(import.meta.url));
|
|
39049
38914
|
const root = dirname11(cur).startsWith("/") ? "/" : ".";
|
|
39050
38915
|
while (cur !== root && cur !== "") {
|
|
39051
|
-
const candidate =
|
|
38916
|
+
const candidate = join20(cur, "package.json");
|
|
39052
38917
|
if (existsSync17(candidate)) {
|
|
39053
|
-
const pkg = JSON.parse(
|
|
38918
|
+
const pkg = JSON.parse(readFileSync15(candidate, "utf-8"));
|
|
39054
38919
|
if (pkg.name === "@arcote.tech/arc-cli") {
|
|
39055
38920
|
return pkg.version ?? "unknown";
|
|
39056
38921
|
}
|
|
@@ -39066,8 +38931,8 @@ function readCliVersion2() {
|
|
|
39066
38931
|
}
|
|
39067
38932
|
}
|
|
39068
38933
|
async function hashDeployConfig(rootDir) {
|
|
39069
|
-
const p2 =
|
|
39070
|
-
const content =
|
|
38934
|
+
const p2 = join20(rootDir, "deploy.arc.json");
|
|
38935
|
+
const content = readFileSync15(p2);
|
|
39071
38936
|
const hasher = new Bun.CryptoHasher("sha256");
|
|
39072
38937
|
hasher.update(content);
|
|
39073
38938
|
hasher.update(readCliVersion2());
|
|
@@ -39075,8 +38940,8 @@ async function hashDeployConfig(rootDir) {
|
|
|
39075
38940
|
}
|
|
39076
38941
|
|
|
39077
38942
|
// src/platform/startup.ts
|
|
39078
|
-
import { existsSync as existsSync19, readFileSync as
|
|
39079
|
-
import { join as
|
|
38943
|
+
import { existsSync as existsSync19, readFileSync as readFileSync16, watch } from "fs";
|
|
38944
|
+
import { join as join22 } from "path";
|
|
39080
38945
|
|
|
39081
38946
|
// ../host/src/create-server.ts
|
|
39082
38947
|
var import_jsonwebtoken = __toESM(require_jsonwebtoken(), 1);
|
|
@@ -40496,7 +40361,7 @@ async function createArcServer(config) {
|
|
|
40496
40361
|
// src/platform/server.ts
|
|
40497
40362
|
init_i18n();
|
|
40498
40363
|
import { existsSync as existsSync18, mkdirSync as mkdirSync14 } from "fs";
|
|
40499
|
-
import { join as
|
|
40364
|
+
import { join as join21 } from "path";
|
|
40500
40365
|
async function resolveDbAdapterFactory(dbPath) {
|
|
40501
40366
|
const databaseUrl = process.env.DATABASE_URL;
|
|
40502
40367
|
if (databaseUrl && databaseUrl.length > 0) {
|
|
@@ -40628,15 +40493,13 @@ function parseArcTokensHeader(header) {
|
|
|
40628
40493
|
return payloads;
|
|
40629
40494
|
}
|
|
40630
40495
|
async function filterManifestForTokens(manifest, moduleAccessMap, tokenPayloads) {
|
|
40631
|
-
const
|
|
40496
|
+
const tokensByName = new Map;
|
|
40632
40497
|
for (const t of tokenPayloads) {
|
|
40633
40498
|
if (t?.tokenType)
|
|
40634
|
-
|
|
40499
|
+
tokensByName.set(t.tokenType, t);
|
|
40635
40500
|
}
|
|
40636
40501
|
const filteredGroups = {};
|
|
40637
40502
|
for (const [name, group] of Object.entries(manifest.groups)) {
|
|
40638
|
-
if (!allowedGroups.has(name))
|
|
40639
|
-
continue;
|
|
40640
40503
|
let allGranted = true;
|
|
40641
40504
|
for (const moduleName of group.modules) {
|
|
40642
40505
|
const access = moduleAccessMap.get(moduleName);
|
|
@@ -40644,9 +40507,7 @@ async function filterManifestForTokens(manifest, moduleAccessMap, tokenPayloads)
|
|
|
40644
40507
|
continue;
|
|
40645
40508
|
let granted = false;
|
|
40646
40509
|
for (const rule of access.rules) {
|
|
40647
|
-
|
|
40648
|
-
continue;
|
|
40649
|
-
const matching = tokenPayloads.find((t) => t.tokenType === name);
|
|
40510
|
+
const matching = tokensByName.get(rule.token.name);
|
|
40650
40511
|
if (!matching)
|
|
40651
40512
|
continue;
|
|
40652
40513
|
granted = rule.check ? await rule.check(matching) : true;
|
|
@@ -40687,28 +40548,28 @@ function staticFilesHandler(ws, devMode, getManifest) {
|
|
|
40687
40548
|
return new Response("Forbidden", { status: 403, headers: ctx.corsHeaders });
|
|
40688
40549
|
}
|
|
40689
40550
|
}
|
|
40690
|
-
return serveFile(
|
|
40551
|
+
return serveFile(join21(ws.browserDir, file), {
|
|
40691
40552
|
...ctx.corsHeaders,
|
|
40692
40553
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
40693
40554
|
});
|
|
40694
40555
|
}
|
|
40695
40556
|
if (path4.startsWith("/locales/"))
|
|
40696
|
-
return serveFile(
|
|
40557
|
+
return serveFile(join21(ws.arcDir, path4.slice(1)), {
|
|
40697
40558
|
...ctx.corsHeaders,
|
|
40698
40559
|
"Cache-Control": devMode ? "no-cache" : "max-age=300,stale-while-revalidate=3600"
|
|
40699
40560
|
});
|
|
40700
40561
|
if (path4.startsWith("/assets/"))
|
|
40701
|
-
return serveFile(
|
|
40562
|
+
return serveFile(join21(ws.assetsDir, path4.slice(8)), {
|
|
40702
40563
|
...ctx.corsHeaders,
|
|
40703
40564
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
40704
40565
|
});
|
|
40705
40566
|
if (path4 === "/styles.css")
|
|
40706
|
-
return serveFile(
|
|
40567
|
+
return serveFile(join21(ws.arcDir, "styles.css"), {
|
|
40707
40568
|
...ctx.corsHeaders,
|
|
40708
40569
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
40709
40570
|
});
|
|
40710
40571
|
if (path4 === "/theme.css")
|
|
40711
|
-
return serveFile(
|
|
40572
|
+
return serveFile(join21(ws.arcDir, "theme.css"), {
|
|
40712
40573
|
...ctx.corsHeaders,
|
|
40713
40574
|
"Cache-Control": devMode ? "no-cache" : "max-age=31536000,immutable"
|
|
40714
40575
|
});
|
|
@@ -40716,7 +40577,7 @@ function staticFilesHandler(ws, devMode, getManifest) {
|
|
|
40716
40577
|
return serveFile(ws.manifest.path, ctx.corsHeaders);
|
|
40717
40578
|
}
|
|
40718
40579
|
if (path4.lastIndexOf(".") > path4.lastIndexOf("/")) {
|
|
40719
|
-
const publicFile =
|
|
40580
|
+
const publicFile = join21(ws.publicDir, path4.slice(1));
|
|
40720
40581
|
if (existsSync18(publicFile))
|
|
40721
40582
|
return serveFile(publicFile, ctx.corsHeaders);
|
|
40722
40583
|
}
|
|
@@ -40871,7 +40732,7 @@ async function startPlatformServer(opts) {
|
|
|
40871
40732
|
stop: () => server.stop()
|
|
40872
40733
|
};
|
|
40873
40734
|
}
|
|
40874
|
-
const dbPath = opts.dbPath ||
|
|
40735
|
+
const dbPath = opts.dbPath || join21(ws.arcDir, "data", "arc.db");
|
|
40875
40736
|
const baseDbFactory = await resolveDbAdapterFactory(dbPath);
|
|
40876
40737
|
let dbAdapterFactory = baseDbFactory;
|
|
40877
40738
|
if (telemetry) {
|
|
@@ -40912,17 +40773,17 @@ async function startPlatformServer(opts) {
|
|
|
40912
40773
|
async function startPlatform(opts) {
|
|
40913
40774
|
const { ws, devMode } = opts;
|
|
40914
40775
|
const port = opts.port ?? parseInt(process.env.PORT || "5005", 10);
|
|
40915
|
-
const dbPath = opts.dbPath ??
|
|
40776
|
+
const dbPath = opts.dbPath ?? join22(ws.rootDir, ".arc", "data", devMode ? "dev.db" : "prod.db");
|
|
40916
40777
|
let manifest;
|
|
40917
40778
|
if (devMode) {
|
|
40918
40779
|
manifest = await buildAll(ws);
|
|
40919
40780
|
} else {
|
|
40920
|
-
const manifestPath =
|
|
40781
|
+
const manifestPath = join22(ws.arcDir, "manifest.json");
|
|
40921
40782
|
if (!existsSync19(manifestPath)) {
|
|
40922
40783
|
err("No build found. Run `arc platform build` first.");
|
|
40923
40784
|
process.exit(1);
|
|
40924
40785
|
}
|
|
40925
|
-
manifest = JSON.parse(
|
|
40786
|
+
manifest = JSON.parse(readFileSync16(manifestPath, "utf-8"));
|
|
40926
40787
|
}
|
|
40927
40788
|
log2("Loading server context...");
|
|
40928
40789
|
const { context: context2, moduleAccess } = await loadServerContext(ws);
|
|
@@ -40998,7 +40859,7 @@ function attachDevWatcher(ws, platform3) {
|
|
|
40998
40859
|
}, 300);
|
|
40999
40860
|
};
|
|
41000
40861
|
for (const pkg of ws.packages) {
|
|
41001
|
-
const srcDir =
|
|
40862
|
+
const srcDir = join22(pkg.path, "src");
|
|
41002
40863
|
if (!existsSync19(srcDir))
|
|
41003
40864
|
continue;
|
|
41004
40865
|
watch(srcDir, { recursive: true }, (_event, filename) => {
|
|
@@ -41009,7 +40870,7 @@ function attachDevWatcher(ws, platform3) {
|
|
|
41009
40870
|
triggerRebuild();
|
|
41010
40871
|
});
|
|
41011
40872
|
}
|
|
41012
|
-
const localesDir =
|
|
40873
|
+
const localesDir = join22(ws.rootDir, "locales");
|
|
41013
40874
|
if (existsSync19(localesDir)) {
|
|
41014
40875
|
watch(localesDir, { recursive: false }, (_event, filename) => {
|
|
41015
40876
|
if (!filename?.endsWith(".po"))
|