githolon 0.113.2 → 0.113.3
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/compile_mountability_entry.js +107 -40
- package/dist/dev-server.mjs +93 -40
- package/dist/full-cli.mjs +107 -40
- package/package.json +2 -2
|
@@ -7050,6 +7050,37 @@ var init_kernel_port = __esm({
|
|
|
7050
7050
|
}
|
|
7051
7051
|
});
|
|
7052
7052
|
|
|
7053
|
+
// ../peer-office/src/runtime/http_origin.ts
|
|
7054
|
+
function httpOrigin(url) {
|
|
7055
|
+
const match = AUTHORITY.exec(url.trim());
|
|
7056
|
+
if (!match) return void 0;
|
|
7057
|
+
const scheme = match[1].toLowerCase();
|
|
7058
|
+
if (scheme !== "http" && scheme !== "https") return void 0;
|
|
7059
|
+
const authority = match[2];
|
|
7060
|
+
const hostAndPort = authority.slice(authority.lastIndexOf("@") + 1);
|
|
7061
|
+
const ipv6 = /^(\[[0-9a-f:.]+\])(?::(\d*))?$/i.exec(hostAndPort);
|
|
7062
|
+
const named = /^([^:[\]\s]+)(?::(\d*))?$/.exec(hostAndPort);
|
|
7063
|
+
const parts = ipv6 ?? named;
|
|
7064
|
+
if (!parts) return void 0;
|
|
7065
|
+
const host = parts[1].toLowerCase();
|
|
7066
|
+
if (host.length === 0 || /[\s<>^`{|}%\\]/.test(host)) return void 0;
|
|
7067
|
+
let port = parts[2] ?? "";
|
|
7068
|
+
if (port !== "") {
|
|
7069
|
+
const value = Number(port);
|
|
7070
|
+
if (!Number.isInteger(value) || value > 65535) return void 0;
|
|
7071
|
+
port = String(value);
|
|
7072
|
+
}
|
|
7073
|
+
return port === "" || port === DEFAULT_PORTS[scheme] ? `${scheme}://${host}` : `${scheme}://${host}:${port}`;
|
|
7074
|
+
}
|
|
7075
|
+
var AUTHORITY, DEFAULT_PORTS;
|
|
7076
|
+
var init_http_origin = __esm({
|
|
7077
|
+
"../peer-office/src/runtime/http_origin.ts"() {
|
|
7078
|
+
"use strict";
|
|
7079
|
+
AUTHORITY = /^([a-z][a-z0-9+.-]*):\/\/([^/?#]*)/i;
|
|
7080
|
+
DEFAULT_PORTS = { http: "80", https: "443" };
|
|
7081
|
+
}
|
|
7082
|
+
});
|
|
7083
|
+
|
|
7053
7084
|
// ../peer-office/src/git_read_lease.ts
|
|
7054
7085
|
import { fromBinary as fromBinary5 } from "@bufbuild/protobuf";
|
|
7055
7086
|
function decodeGitReadLease(bytes, workspace, nowUnixSeconds = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
@@ -7401,6 +7432,7 @@ var stableIdentifier, normalizeProfile, originOf2, ReplicaPlacementDirectiveKind
|
|
|
7401
7432
|
var init_placement_desk = __esm({
|
|
7402
7433
|
"../peer-office/src/runtime/placement_desk.ts"() {
|
|
7403
7434
|
"use strict";
|
|
7435
|
+
init_http_origin();
|
|
7404
7436
|
init_provider_origins();
|
|
7405
7437
|
init_kernel_pb();
|
|
7406
7438
|
init_placement_desk_pb();
|
|
@@ -7425,14 +7457,7 @@ var init_placement_desk = __esm({
|
|
|
7425
7457
|
...servedOrigin === void 0 ? {} : { servedOrigin }
|
|
7426
7458
|
});
|
|
7427
7459
|
};
|
|
7428
|
-
originOf2 =
|
|
7429
|
-
try {
|
|
7430
|
-
const parsed = new URL(url);
|
|
7431
|
-
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.origin : void 0;
|
|
7432
|
-
} catch {
|
|
7433
|
-
return void 0;
|
|
7434
|
-
}
|
|
7435
|
-
};
|
|
7460
|
+
originOf2 = httpOrigin;
|
|
7436
7461
|
ReplicaPlacementDirectiveKind = Object.freeze({
|
|
7437
7462
|
None: "none",
|
|
7438
7463
|
Cache: "cache",
|
|
@@ -13599,7 +13624,10 @@ var init_read_maintenance_desk = __esm({
|
|
|
13599
13624
|
...background ? { background } : {},
|
|
13600
13625
|
...awaited || existing?.awaited ? { awaited: true } : {},
|
|
13601
13626
|
failures: existing?.failures ?? 0,
|
|
13602
|
-
|
|
13627
|
+
// A foreground read may retry at once. Upkeep owed by a write or a sync keeps any back-off
|
|
13628
|
+
// it is already serving: otherwise every write retried a failing upkeep immediately, and a
|
|
13629
|
+
// workspace whose upkeep could not succeed retried on every write (CAP-693).
|
|
13630
|
+
retryNotBeforeNanoseconds: isReadDemand ? 0n : existing?.retryNotBeforeNanoseconds ?? 0n
|
|
13603
13631
|
});
|
|
13604
13632
|
if (isReadDemand && (!existing?.read || existing.read.owedByAdvance)) {
|
|
13605
13633
|
const entries = [...this.#pending.entries()];
|
|
@@ -14248,18 +14276,17 @@ var init_subscription_manager = __esm({
|
|
|
14248
14276
|
#requestReadMaintenance;
|
|
14249
14277
|
#clock;
|
|
14250
14278
|
#subscriptions = /* @__PURE__ */ new Map();
|
|
14251
|
-
/** Watches owed a re-read, drained one query group per
|
|
14279
|
+
/** Watches owed a re-read, drained one query group per office turn (see [drainOwedTurn]). */
|
|
14252
14280
|
#owed = /* @__PURE__ */ new Set();
|
|
14253
|
-
#
|
|
14254
|
-
#draining = false;
|
|
14281
|
+
#deferRefreshes;
|
|
14255
14282
|
#sequence = 0n;
|
|
14256
|
-
constructor(queries, sessions, events, requestReadMaintenance, clock,
|
|
14283
|
+
constructor(queries, sessions, events, requestReadMaintenance, clock, deferRefreshes = false) {
|
|
14257
14284
|
this.#queries = queries;
|
|
14258
14285
|
this.#sessions = sessions;
|
|
14259
14286
|
this.#events = events;
|
|
14260
14287
|
this.#requestReadMaintenance = requestReadMaintenance;
|
|
14261
14288
|
this.#clock = clock;
|
|
14262
|
-
this.#
|
|
14289
|
+
this.#deferRefreshes = deferRefreshes;
|
|
14263
14290
|
}
|
|
14264
14291
|
start(request, command) {
|
|
14265
14292
|
if (!command.subscriptionId) throw new Error("watch requires a subscription identity");
|
|
@@ -14365,34 +14392,33 @@ var init_subscription_manager = __esm({
|
|
|
14365
14392
|
* or replace current authorization. Each watch still owns its delivery state.
|
|
14366
14393
|
*/
|
|
14367
14394
|
#refreshMatching(matches, cause) {
|
|
14368
|
-
if (this.#
|
|
14395
|
+
if (this.#deferRefreshes && !cause) {
|
|
14369
14396
|
for (const [id, subscription] of this.#subscriptions) {
|
|
14370
14397
|
if (subscription.request.query && matches(subscription)) this.#owed.add(id);
|
|
14371
14398
|
}
|
|
14372
|
-
this.#drain();
|
|
14373
14399
|
return;
|
|
14374
14400
|
}
|
|
14375
14401
|
this.#refreshGroups(this.#groups(matches), cause);
|
|
14376
14402
|
}
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
this.#
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
|
|
14386
|
-
|
|
14387
|
-
|
|
14388
|
-
|
|
14389
|
-
|
|
14390
|
-
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
14394
|
-
|
|
14395
|
-
|
|
14403
|
+
/** Whether any watch is owed a re-read: the office's next drive() is due at once. */
|
|
14404
|
+
get owesRefresh() {
|
|
14405
|
+
return this.#owed.size > 0;
|
|
14406
|
+
}
|
|
14407
|
+
/** One office turn of owed re-reads: the first owed watch's query group. False when none was owed. */
|
|
14408
|
+
drainOwedTurn() {
|
|
14409
|
+
if (this.#owed.size === 0) return false;
|
|
14410
|
+
const first = this.#owed.values().next().value;
|
|
14411
|
+
const lead = this.#subscriptions.get(first);
|
|
14412
|
+
if (!lead?.request.query) {
|
|
14413
|
+
this.#owed.delete(first);
|
|
14414
|
+
return true;
|
|
14415
|
+
}
|
|
14416
|
+
const declaration = toBinary15(QueryRequestSchema, lead.request.query);
|
|
14417
|
+
const session = lead.request.session;
|
|
14418
|
+
const group = this.#groups((subscription) => subscription.request.session === session && this.#owed.has(subscription.request.subscriptionId) && sameBytes(toBinary15(QueryRequestSchema, subscription.request.query), declaration));
|
|
14419
|
+
for (const each of group) for (const watch of each.watches) this.#owed.delete(watch.request.subscriptionId);
|
|
14420
|
+
this.#refreshGroups(group);
|
|
14421
|
+
return true;
|
|
14396
14422
|
}
|
|
14397
14423
|
#groups(matches) {
|
|
14398
14424
|
const groups = [];
|
|
@@ -14512,6 +14538,44 @@ var init_subscription_manager = __esm({
|
|
|
14512
14538
|
}
|
|
14513
14539
|
});
|
|
14514
14540
|
|
|
14541
|
+
// ../peer-office/src/runtime/shell_contract.ts
|
|
14542
|
+
function declaredShellContract(scope = globalThis) {
|
|
14543
|
+
const declared = scope.__nomosShellContract;
|
|
14544
|
+
return declared === void 0 ? 1 : Number(declared);
|
|
14545
|
+
}
|
|
14546
|
+
function assertShellContract(scope = globalThis) {
|
|
14547
|
+
const declared = declaredShellContract(scope);
|
|
14548
|
+
if (!Number.isInteger(declared) || declared < SHELL_CONTRACT_MINIMUM) {
|
|
14549
|
+
throw new Error(`nomos.runtime.shell_contract_unsupported: this runtime needs shell contract ${SHELL_CONTRACT_MINIMUM} or later; the shell declares ${String(declared)}`);
|
|
14550
|
+
}
|
|
14551
|
+
}
|
|
14552
|
+
var SHELL_CONTRACT_V1, SHELL_CONTRACT_V2, SHELL_CONTRACT_MINIMUM;
|
|
14553
|
+
var init_shell_contract = __esm({
|
|
14554
|
+
"../peer-office/src/runtime/shell_contract.ts"() {
|
|
14555
|
+
"use strict";
|
|
14556
|
+
SHELL_CONTRACT_V1 = Object.freeze({
|
|
14557
|
+
version: 1,
|
|
14558
|
+
/** Host globals beyond ECMAScript 2022, which every shell supplies. */
|
|
14559
|
+
host: Object.freeze(["TextEncoder", "TextDecoder", "queueMicrotask", "console"]),
|
|
14560
|
+
/** Nomos bridges a native bootstrap installs for the ports it hands to peerOffice.open. */
|
|
14561
|
+
bridges: Object.freeze([
|
|
14562
|
+
"__nomosKernel",
|
|
14563
|
+
"__nomosCredentialVault",
|
|
14564
|
+
"__nomosProfile",
|
|
14565
|
+
"__nomosObservations",
|
|
14566
|
+
"__nomosCustodyStorage",
|
|
14567
|
+
"__nomosPeerDeskStore",
|
|
14568
|
+
"__nomosSyncDiagnostic",
|
|
14569
|
+
"__nomosShellContract"
|
|
14570
|
+
]),
|
|
14571
|
+
/** Globals the runtime may only probe: used behind their own `typeof` test, never bare. */
|
|
14572
|
+
probed: Object.freeze(["process", "Deno", "Bun", "define"])
|
|
14573
|
+
});
|
|
14574
|
+
SHELL_CONTRACT_V2 = Object.freeze({ ...SHELL_CONTRACT_V1, version: 2 });
|
|
14575
|
+
SHELL_CONTRACT_MINIMUM = 1;
|
|
14576
|
+
}
|
|
14577
|
+
});
|
|
14578
|
+
|
|
14515
14579
|
// ../peer-office/src/runtime/replica_follow_state.ts
|
|
14516
14580
|
function reduceReplicaFollow(state, event, policy) {
|
|
14517
14581
|
switch (event.case) {
|
|
@@ -22741,6 +22805,7 @@ var init_peer_office = __esm({
|
|
|
22741
22805
|
init_residency_pins();
|
|
22742
22806
|
init_maintenance_desk_pb();
|
|
22743
22807
|
init_subscription_manager();
|
|
22808
|
+
init_shell_contract();
|
|
22744
22809
|
init_replica_follow_controller();
|
|
22745
22810
|
init_replica_follow_desk();
|
|
22746
22811
|
init_local_copy_drop();
|
|
@@ -22937,10 +23002,9 @@ var init_peer_office = __esm({
|
|
|
22937
23002
|
this.#trace,
|
|
22938
23003
|
(session) => this.#readMaintenance.schedule(session, ReadMaintenanceCause.READ_DEBT),
|
|
22939
23004
|
observations,
|
|
22940
|
-
// An interactive peer keeps its thread responsive while watches catch up
|
|
22941
|
-
|
|
22942
|
-
|
|
22943
|
-
} : void 0
|
|
23005
|
+
// An interactive peer keeps its thread responsive while watches catch up: owed re-reads
|
|
23006
|
+
// wait for its drive() turns.
|
|
23007
|
+
this.#interactivePeer
|
|
22944
23008
|
);
|
|
22945
23009
|
this.#application = new ApplicationDesk({
|
|
22946
23010
|
onAdmitted: (session) => {
|
|
@@ -23347,7 +23411,9 @@ var init_peer_office = __esm({
|
|
|
23347
23411
|
* mirrors queue/backoff state.
|
|
23348
23412
|
*/
|
|
23349
23413
|
drive() {
|
|
23350
|
-
|
|
23414
|
+
if (this.#subscriptions.drainOwedTurn()) return 0n;
|
|
23415
|
+
const wake = this.#maintenance.drive();
|
|
23416
|
+
return this.#subscriptions.owesRefresh ? 0n : wake;
|
|
23351
23417
|
}
|
|
23352
23418
|
/**
|
|
23353
23419
|
* Carry one exact maintenance demand through a durable host continuation.
|
|
@@ -24308,6 +24374,7 @@ var init_peer_office = __esm({
|
|
|
24308
24374
|
};
|
|
24309
24375
|
peerOffice = {
|
|
24310
24376
|
open(kernel, credentials, profile, observations, custodyStorage, peerDeskStore) {
|
|
24377
|
+
assertShellContract();
|
|
24311
24378
|
return new PeerOffice(kernel, credentials, profile, observations, custodyStorage, peerDeskStore);
|
|
24312
24379
|
},
|
|
24313
24380
|
Peer: PeerOffice
|
package/dist/dev-server.mjs
CHANGED
|
@@ -4954,6 +4954,31 @@ var KernelPort = class {
|
|
|
4954
4954
|
// ../peer-office/src/runtime/placement_desk.ts
|
|
4955
4955
|
import { create as create14 } from "@bufbuild/protobuf";
|
|
4956
4956
|
|
|
4957
|
+
// ../peer-office/src/runtime/http_origin.ts
|
|
4958
|
+
var AUTHORITY = /^([a-z][a-z0-9+.-]*):\/\/([^/?#]*)/i;
|
|
4959
|
+
var DEFAULT_PORTS = { http: "80", https: "443" };
|
|
4960
|
+
function httpOrigin(url) {
|
|
4961
|
+
const match = AUTHORITY.exec(url.trim());
|
|
4962
|
+
if (!match) return void 0;
|
|
4963
|
+
const scheme = match[1].toLowerCase();
|
|
4964
|
+
if (scheme !== "http" && scheme !== "https") return void 0;
|
|
4965
|
+
const authority = match[2];
|
|
4966
|
+
const hostAndPort = authority.slice(authority.lastIndexOf("@") + 1);
|
|
4967
|
+
const ipv6 = /^(\[[0-9a-f:.]+\])(?::(\d*))?$/i.exec(hostAndPort);
|
|
4968
|
+
const named = /^([^:[\]\s]+)(?::(\d*))?$/.exec(hostAndPort);
|
|
4969
|
+
const parts = ipv6 ?? named;
|
|
4970
|
+
if (!parts) return void 0;
|
|
4971
|
+
const host = parts[1].toLowerCase();
|
|
4972
|
+
if (host.length === 0 || /[\s<>^`{|}%\\]/.test(host)) return void 0;
|
|
4973
|
+
let port = parts[2] ?? "";
|
|
4974
|
+
if (port !== "") {
|
|
4975
|
+
const value = Number(port);
|
|
4976
|
+
if (!Number.isInteger(value) || value > 65535) return void 0;
|
|
4977
|
+
port = String(value);
|
|
4978
|
+
}
|
|
4979
|
+
return port === "" || port === DEFAULT_PORTS[scheme] ? `${scheme}://${host}` : `${scheme}://${host}:${port}`;
|
|
4980
|
+
}
|
|
4981
|
+
|
|
4957
4982
|
// ../peer-office/src/runtime/provider_origins.ts
|
|
4958
4983
|
import { create as create13 } from "@bufbuild/protobuf";
|
|
4959
4984
|
import { fromBinary as fromBinary10 } from "@bufbuild/protobuf";
|
|
@@ -5292,14 +5317,7 @@ var normalizeProfile = (profile) => {
|
|
|
5292
5317
|
...servedOrigin === void 0 ? {} : { servedOrigin }
|
|
5293
5318
|
});
|
|
5294
5319
|
};
|
|
5295
|
-
var originOf2 =
|
|
5296
|
-
try {
|
|
5297
|
-
const parsed = new URL(url);
|
|
5298
|
-
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.origin : void 0;
|
|
5299
|
-
} catch {
|
|
5300
|
-
return void 0;
|
|
5301
|
-
}
|
|
5302
|
-
};
|
|
5320
|
+
var originOf2 = httpOrigin;
|
|
5303
5321
|
var ReplicaPlacementDirectiveKind = Object.freeze({
|
|
5304
5322
|
None: "none",
|
|
5305
5323
|
Cache: "cache",
|
|
@@ -11138,7 +11156,10 @@ var ReadMaintenanceDesk = class {
|
|
|
11138
11156
|
...background ? { background } : {},
|
|
11139
11157
|
...awaited || existing?.awaited ? { awaited: true } : {},
|
|
11140
11158
|
failures: existing?.failures ?? 0,
|
|
11141
|
-
|
|
11159
|
+
// A foreground read may retry at once. Upkeep owed by a write or a sync keeps any back-off
|
|
11160
|
+
// it is already serving: otherwise every write retried a failing upkeep immediately, and a
|
|
11161
|
+
// workspace whose upkeep could not succeed retried on every write (CAP-693).
|
|
11162
|
+
retryNotBeforeNanoseconds: isReadDemand ? 0n : existing?.retryNotBeforeNanoseconds ?? 0n
|
|
11142
11163
|
});
|
|
11143
11164
|
if (isReadDemand && (!existing?.read || existing.read.owedByAdvance)) {
|
|
11144
11165
|
const entries = [...this.#pending.entries()];
|
|
@@ -11746,18 +11767,17 @@ var SubscriptionManager = class {
|
|
|
11746
11767
|
#requestReadMaintenance;
|
|
11747
11768
|
#clock;
|
|
11748
11769
|
#subscriptions = /* @__PURE__ */ new Map();
|
|
11749
|
-
/** Watches owed a re-read, drained one query group per
|
|
11770
|
+
/** Watches owed a re-read, drained one query group per office turn (see [drainOwedTurn]). */
|
|
11750
11771
|
#owed = /* @__PURE__ */ new Set();
|
|
11751
|
-
#
|
|
11752
|
-
#draining = false;
|
|
11772
|
+
#deferRefreshes;
|
|
11753
11773
|
#sequence = 0n;
|
|
11754
|
-
constructor(queries, sessions, events, requestReadMaintenance, clock,
|
|
11774
|
+
constructor(queries, sessions, events, requestReadMaintenance, clock, deferRefreshes = false) {
|
|
11755
11775
|
this.#queries = queries;
|
|
11756
11776
|
this.#sessions = sessions;
|
|
11757
11777
|
this.#events = events;
|
|
11758
11778
|
this.#requestReadMaintenance = requestReadMaintenance;
|
|
11759
11779
|
this.#clock = clock;
|
|
11760
|
-
this.#
|
|
11780
|
+
this.#deferRefreshes = deferRefreshes;
|
|
11761
11781
|
}
|
|
11762
11782
|
start(request, command) {
|
|
11763
11783
|
if (!command.subscriptionId) throw new Error("watch requires a subscription identity");
|
|
@@ -11863,34 +11883,33 @@ var SubscriptionManager = class {
|
|
|
11863
11883
|
* or replace current authorization. Each watch still owns its delivery state.
|
|
11864
11884
|
*/
|
|
11865
11885
|
#refreshMatching(matches, cause) {
|
|
11866
|
-
if (this.#
|
|
11886
|
+
if (this.#deferRefreshes && !cause) {
|
|
11867
11887
|
for (const [id, subscription] of this.#subscriptions) {
|
|
11868
11888
|
if (subscription.request.query && matches(subscription)) this.#owed.add(id);
|
|
11869
11889
|
}
|
|
11870
|
-
this.#drain();
|
|
11871
11890
|
return;
|
|
11872
11891
|
}
|
|
11873
11892
|
this.#refreshGroups(this.#groups(matches), cause);
|
|
11874
11893
|
}
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
this.#
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
+
/** Whether any watch is owed a re-read: the office's next drive() is due at once. */
|
|
11895
|
+
get owesRefresh() {
|
|
11896
|
+
return this.#owed.size > 0;
|
|
11897
|
+
}
|
|
11898
|
+
/** One office turn of owed re-reads: the first owed watch's query group. False when none was owed. */
|
|
11899
|
+
drainOwedTurn() {
|
|
11900
|
+
if (this.#owed.size === 0) return false;
|
|
11901
|
+
const first = this.#owed.values().next().value;
|
|
11902
|
+
const lead = this.#subscriptions.get(first);
|
|
11903
|
+
if (!lead?.request.query) {
|
|
11904
|
+
this.#owed.delete(first);
|
|
11905
|
+
return true;
|
|
11906
|
+
}
|
|
11907
|
+
const declaration = toBinary20(QueryRequestSchema, lead.request.query);
|
|
11908
|
+
const session = lead.request.session;
|
|
11909
|
+
const group = this.#groups((subscription) => subscription.request.session === session && this.#owed.has(subscription.request.subscriptionId) && sameBytes(toBinary20(QueryRequestSchema, subscription.request.query), declaration));
|
|
11910
|
+
for (const each of group) for (const watch of each.watches) this.#owed.delete(watch.request.subscriptionId);
|
|
11911
|
+
this.#refreshGroups(group);
|
|
11912
|
+
return true;
|
|
11894
11913
|
}
|
|
11895
11914
|
#groups(matches) {
|
|
11896
11915
|
const groups = [];
|
|
@@ -12014,6 +12033,38 @@ function createSyntheticRequest(requestId) {
|
|
|
12014
12033
|
});
|
|
12015
12034
|
}
|
|
12016
12035
|
|
|
12036
|
+
// ../peer-office/src/runtime/shell_contract.ts
|
|
12037
|
+
var SHELL_CONTRACT_V1 = Object.freeze({
|
|
12038
|
+
version: 1,
|
|
12039
|
+
/** Host globals beyond ECMAScript 2022, which every shell supplies. */
|
|
12040
|
+
host: Object.freeze(["TextEncoder", "TextDecoder", "queueMicrotask", "console"]),
|
|
12041
|
+
/** Nomos bridges a native bootstrap installs for the ports it hands to peerOffice.open. */
|
|
12042
|
+
bridges: Object.freeze([
|
|
12043
|
+
"__nomosKernel",
|
|
12044
|
+
"__nomosCredentialVault",
|
|
12045
|
+
"__nomosProfile",
|
|
12046
|
+
"__nomosObservations",
|
|
12047
|
+
"__nomosCustodyStorage",
|
|
12048
|
+
"__nomosPeerDeskStore",
|
|
12049
|
+
"__nomosSyncDiagnostic",
|
|
12050
|
+
"__nomosShellContract"
|
|
12051
|
+
]),
|
|
12052
|
+
/** Globals the runtime may only probe: used behind their own `typeof` test, never bare. */
|
|
12053
|
+
probed: Object.freeze(["process", "Deno", "Bun", "define"])
|
|
12054
|
+
});
|
|
12055
|
+
var SHELL_CONTRACT_V2 = Object.freeze({ ...SHELL_CONTRACT_V1, version: 2 });
|
|
12056
|
+
var SHELL_CONTRACT_MINIMUM = 1;
|
|
12057
|
+
function declaredShellContract(scope = globalThis) {
|
|
12058
|
+
const declared = scope.__nomosShellContract;
|
|
12059
|
+
return declared === void 0 ? 1 : Number(declared);
|
|
12060
|
+
}
|
|
12061
|
+
function assertShellContract(scope = globalThis) {
|
|
12062
|
+
const declared = declaredShellContract(scope);
|
|
12063
|
+
if (!Number.isInteger(declared) || declared < SHELL_CONTRACT_MINIMUM) {
|
|
12064
|
+
throw new Error(`nomos.runtime.shell_contract_unsupported: this runtime needs shell contract ${SHELL_CONTRACT_MINIMUM} or later; the shell declares ${String(declared)}`);
|
|
12065
|
+
}
|
|
12066
|
+
}
|
|
12067
|
+
|
|
12017
12068
|
// ../peer-office/src/runtime/replica_follow_state.ts
|
|
12018
12069
|
var ReplicaFollowPhase = Object.freeze({
|
|
12019
12070
|
Desired: "desired",
|
|
@@ -19990,10 +20041,9 @@ var PeerOffice = class {
|
|
|
19990
20041
|
this.#trace,
|
|
19991
20042
|
(session) => this.#readMaintenance.schedule(session, ReadMaintenanceCause.READ_DEBT),
|
|
19992
20043
|
observations,
|
|
19993
|
-
// An interactive peer keeps its thread responsive while watches catch up
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
} : void 0
|
|
20044
|
+
// An interactive peer keeps its thread responsive while watches catch up: owed re-reads
|
|
20045
|
+
// wait for its drive() turns.
|
|
20046
|
+
this.#interactivePeer
|
|
19997
20047
|
);
|
|
19998
20048
|
this.#application = new ApplicationDesk({
|
|
19999
20049
|
onAdmitted: (session) => {
|
|
@@ -20400,7 +20450,9 @@ var PeerOffice = class {
|
|
|
20400
20450
|
* mirrors queue/backoff state.
|
|
20401
20451
|
*/
|
|
20402
20452
|
drive() {
|
|
20403
|
-
|
|
20453
|
+
if (this.#subscriptions.drainOwedTurn()) return 0n;
|
|
20454
|
+
const wake = this.#maintenance.drive();
|
|
20455
|
+
return this.#subscriptions.owesRefresh ? 0n : wake;
|
|
20404
20456
|
}
|
|
20405
20457
|
/**
|
|
20406
20458
|
* Carry one exact maintenance demand through a durable host continuation.
|
|
@@ -21361,6 +21413,7 @@ var PeerOffice = class {
|
|
|
21361
21413
|
};
|
|
21362
21414
|
var peerOffice = {
|
|
21363
21415
|
open(kernel, credentials, profile, observations, custodyStorage, peerDeskStore) {
|
|
21416
|
+
assertShellContract();
|
|
21364
21417
|
return new PeerOffice(kernel, credentials, profile, observations, custodyStorage, peerDeskStore);
|
|
21365
21418
|
},
|
|
21366
21419
|
Peer: PeerOffice
|
package/dist/full-cli.mjs
CHANGED
|
@@ -12985,6 +12985,37 @@ var init_kernel_port = __esm({
|
|
|
12985
12985
|
}
|
|
12986
12986
|
});
|
|
12987
12987
|
|
|
12988
|
+
// ../peer-office/src/runtime/http_origin.ts
|
|
12989
|
+
function httpOrigin(url) {
|
|
12990
|
+
const match = AUTHORITY.exec(url.trim());
|
|
12991
|
+
if (!match) return void 0;
|
|
12992
|
+
const scheme = match[1].toLowerCase();
|
|
12993
|
+
if (scheme !== "http" && scheme !== "https") return void 0;
|
|
12994
|
+
const authority = match[2];
|
|
12995
|
+
const hostAndPort = authority.slice(authority.lastIndexOf("@") + 1);
|
|
12996
|
+
const ipv6 = /^(\[[0-9a-f:.]+\])(?::(\d*))?$/i.exec(hostAndPort);
|
|
12997
|
+
const named = /^([^:[\]\s]+)(?::(\d*))?$/.exec(hostAndPort);
|
|
12998
|
+
const parts = ipv6 ?? named;
|
|
12999
|
+
if (!parts) return void 0;
|
|
13000
|
+
const host2 = parts[1].toLowerCase();
|
|
13001
|
+
if (host2.length === 0 || /[\s<>^`{|}%\\]/.test(host2)) return void 0;
|
|
13002
|
+
let port = parts[2] ?? "";
|
|
13003
|
+
if (port !== "") {
|
|
13004
|
+
const value = Number(port);
|
|
13005
|
+
if (!Number.isInteger(value) || value > 65535) return void 0;
|
|
13006
|
+
port = String(value);
|
|
13007
|
+
}
|
|
13008
|
+
return port === "" || port === DEFAULT_PORTS[scheme] ? `${scheme}://${host2}` : `${scheme}://${host2}:${port}`;
|
|
13009
|
+
}
|
|
13010
|
+
var AUTHORITY, DEFAULT_PORTS;
|
|
13011
|
+
var init_http_origin = __esm({
|
|
13012
|
+
"../peer-office/src/runtime/http_origin.ts"() {
|
|
13013
|
+
"use strict";
|
|
13014
|
+
AUTHORITY = /^([a-z][a-z0-9+.-]*):\/\/([^/?#]*)/i;
|
|
13015
|
+
DEFAULT_PORTS = { http: "80", https: "443" };
|
|
13016
|
+
}
|
|
13017
|
+
});
|
|
13018
|
+
|
|
12988
13019
|
// ../peer-office/src/git_read_lease.ts
|
|
12989
13020
|
import { fromBinary as fromBinary5 } from "@bufbuild/protobuf";
|
|
12990
13021
|
function decodeGitReadLease(bytes, workspace, nowUnixSeconds = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
@@ -13336,6 +13367,7 @@ var stableIdentifier, normalizeProfile, originOf2, ReplicaPlacementDirectiveKind
|
|
|
13336
13367
|
var init_placement_desk = __esm({
|
|
13337
13368
|
"../peer-office/src/runtime/placement_desk.ts"() {
|
|
13338
13369
|
"use strict";
|
|
13370
|
+
init_http_origin();
|
|
13339
13371
|
init_provider_origins();
|
|
13340
13372
|
init_kernel_pb();
|
|
13341
13373
|
init_placement_desk_pb();
|
|
@@ -13360,14 +13392,7 @@ var init_placement_desk = __esm({
|
|
|
13360
13392
|
...servedOrigin === void 0 ? {} : { servedOrigin }
|
|
13361
13393
|
});
|
|
13362
13394
|
};
|
|
13363
|
-
originOf2 =
|
|
13364
|
-
try {
|
|
13365
|
-
const parsed = new URL(url);
|
|
13366
|
-
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.origin : void 0;
|
|
13367
|
-
} catch {
|
|
13368
|
-
return void 0;
|
|
13369
|
-
}
|
|
13370
|
-
};
|
|
13395
|
+
originOf2 = httpOrigin;
|
|
13371
13396
|
ReplicaPlacementDirectiveKind = Object.freeze({
|
|
13372
13397
|
None: "none",
|
|
13373
13398
|
Cache: "cache",
|
|
@@ -19534,7 +19559,10 @@ var init_read_maintenance_desk = __esm({
|
|
|
19534
19559
|
...background ? { background } : {},
|
|
19535
19560
|
...awaited || existing?.awaited ? { awaited: true } : {},
|
|
19536
19561
|
failures: existing?.failures ?? 0,
|
|
19537
|
-
|
|
19562
|
+
// A foreground read may retry at once. Upkeep owed by a write or a sync keeps any back-off
|
|
19563
|
+
// it is already serving: otherwise every write retried a failing upkeep immediately, and a
|
|
19564
|
+
// workspace whose upkeep could not succeed retried on every write (CAP-693).
|
|
19565
|
+
retryNotBeforeNanoseconds: isReadDemand ? 0n : existing?.retryNotBeforeNanoseconds ?? 0n
|
|
19538
19566
|
});
|
|
19539
19567
|
if (isReadDemand && (!existing?.read || existing.read.owedByAdvance)) {
|
|
19540
19568
|
const entries = [...this.#pending.entries()];
|
|
@@ -20183,18 +20211,17 @@ var init_subscription_manager = __esm({
|
|
|
20183
20211
|
#requestReadMaintenance;
|
|
20184
20212
|
#clock;
|
|
20185
20213
|
#subscriptions = /* @__PURE__ */ new Map();
|
|
20186
|
-
/** Watches owed a re-read, drained one query group per
|
|
20214
|
+
/** Watches owed a re-read, drained one query group per office turn (see [drainOwedTurn]). */
|
|
20187
20215
|
#owed = /* @__PURE__ */ new Set();
|
|
20188
|
-
#
|
|
20189
|
-
#draining = false;
|
|
20216
|
+
#deferRefreshes;
|
|
20190
20217
|
#sequence = 0n;
|
|
20191
|
-
constructor(queries, sessions, events, requestReadMaintenance, clock,
|
|
20218
|
+
constructor(queries, sessions, events, requestReadMaintenance, clock, deferRefreshes = false) {
|
|
20192
20219
|
this.#queries = queries;
|
|
20193
20220
|
this.#sessions = sessions;
|
|
20194
20221
|
this.#events = events;
|
|
20195
20222
|
this.#requestReadMaintenance = requestReadMaintenance;
|
|
20196
20223
|
this.#clock = clock;
|
|
20197
|
-
this.#
|
|
20224
|
+
this.#deferRefreshes = deferRefreshes;
|
|
20198
20225
|
}
|
|
20199
20226
|
start(request, command) {
|
|
20200
20227
|
if (!command.subscriptionId) throw new Error("watch requires a subscription identity");
|
|
@@ -20300,34 +20327,33 @@ var init_subscription_manager = __esm({
|
|
|
20300
20327
|
* or replace current authorization. Each watch still owns its delivery state.
|
|
20301
20328
|
*/
|
|
20302
20329
|
#refreshMatching(matches, cause) {
|
|
20303
|
-
if (this.#
|
|
20330
|
+
if (this.#deferRefreshes && !cause) {
|
|
20304
20331
|
for (const [id, subscription] of this.#subscriptions) {
|
|
20305
20332
|
if (subscription.request.query && matches(subscription)) this.#owed.add(id);
|
|
20306
20333
|
}
|
|
20307
|
-
this.#drain();
|
|
20308
20334
|
return;
|
|
20309
20335
|
}
|
|
20310
20336
|
this.#refreshGroups(this.#groups(matches), cause);
|
|
20311
20337
|
}
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
this.#
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
|
|
20322
|
-
|
|
20323
|
-
|
|
20324
|
-
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20338
|
+
/** Whether any watch is owed a re-read: the office's next drive() is due at once. */
|
|
20339
|
+
get owesRefresh() {
|
|
20340
|
+
return this.#owed.size > 0;
|
|
20341
|
+
}
|
|
20342
|
+
/** One office turn of owed re-reads: the first owed watch's query group. False when none was owed. */
|
|
20343
|
+
drainOwedTurn() {
|
|
20344
|
+
if (this.#owed.size === 0) return false;
|
|
20345
|
+
const first = this.#owed.values().next().value;
|
|
20346
|
+
const lead = this.#subscriptions.get(first);
|
|
20347
|
+
if (!lead?.request.query) {
|
|
20348
|
+
this.#owed.delete(first);
|
|
20349
|
+
return true;
|
|
20350
|
+
}
|
|
20351
|
+
const declaration = toBinary15(QueryRequestSchema, lead.request.query);
|
|
20352
|
+
const session = lead.request.session;
|
|
20353
|
+
const group = this.#groups((subscription) => subscription.request.session === session && this.#owed.has(subscription.request.subscriptionId) && sameBytes(toBinary15(QueryRequestSchema, subscription.request.query), declaration));
|
|
20354
|
+
for (const each of group) for (const watch of each.watches) this.#owed.delete(watch.request.subscriptionId);
|
|
20355
|
+
this.#refreshGroups(group);
|
|
20356
|
+
return true;
|
|
20331
20357
|
}
|
|
20332
20358
|
#groups(matches) {
|
|
20333
20359
|
const groups = [];
|
|
@@ -20447,6 +20473,44 @@ var init_subscription_manager = __esm({
|
|
|
20447
20473
|
}
|
|
20448
20474
|
});
|
|
20449
20475
|
|
|
20476
|
+
// ../peer-office/src/runtime/shell_contract.ts
|
|
20477
|
+
function declaredShellContract(scope = globalThis) {
|
|
20478
|
+
const declared = scope.__nomosShellContract;
|
|
20479
|
+
return declared === void 0 ? 1 : Number(declared);
|
|
20480
|
+
}
|
|
20481
|
+
function assertShellContract(scope = globalThis) {
|
|
20482
|
+
const declared = declaredShellContract(scope);
|
|
20483
|
+
if (!Number.isInteger(declared) || declared < SHELL_CONTRACT_MINIMUM) {
|
|
20484
|
+
throw new Error(`nomos.runtime.shell_contract_unsupported: this runtime needs shell contract ${SHELL_CONTRACT_MINIMUM} or later; the shell declares ${String(declared)}`);
|
|
20485
|
+
}
|
|
20486
|
+
}
|
|
20487
|
+
var SHELL_CONTRACT_V1, SHELL_CONTRACT_V2, SHELL_CONTRACT_MINIMUM;
|
|
20488
|
+
var init_shell_contract = __esm({
|
|
20489
|
+
"../peer-office/src/runtime/shell_contract.ts"() {
|
|
20490
|
+
"use strict";
|
|
20491
|
+
SHELL_CONTRACT_V1 = Object.freeze({
|
|
20492
|
+
version: 1,
|
|
20493
|
+
/** Host globals beyond ECMAScript 2022, which every shell supplies. */
|
|
20494
|
+
host: Object.freeze(["TextEncoder", "TextDecoder", "queueMicrotask", "console"]),
|
|
20495
|
+
/** Nomos bridges a native bootstrap installs for the ports it hands to peerOffice.open. */
|
|
20496
|
+
bridges: Object.freeze([
|
|
20497
|
+
"__nomosKernel",
|
|
20498
|
+
"__nomosCredentialVault",
|
|
20499
|
+
"__nomosProfile",
|
|
20500
|
+
"__nomosObservations",
|
|
20501
|
+
"__nomosCustodyStorage",
|
|
20502
|
+
"__nomosPeerDeskStore",
|
|
20503
|
+
"__nomosSyncDiagnostic",
|
|
20504
|
+
"__nomosShellContract"
|
|
20505
|
+
]),
|
|
20506
|
+
/** Globals the runtime may only probe: used behind their own `typeof` test, never bare. */
|
|
20507
|
+
probed: Object.freeze(["process", "Deno", "Bun", "define"])
|
|
20508
|
+
});
|
|
20509
|
+
SHELL_CONTRACT_V2 = Object.freeze({ ...SHELL_CONTRACT_V1, version: 2 });
|
|
20510
|
+
SHELL_CONTRACT_MINIMUM = 1;
|
|
20511
|
+
}
|
|
20512
|
+
});
|
|
20513
|
+
|
|
20450
20514
|
// ../peer-office/src/runtime/replica_follow_state.ts
|
|
20451
20515
|
function reduceReplicaFollow(state, event, policy) {
|
|
20452
20516
|
switch (event.case) {
|
|
@@ -28676,6 +28740,7 @@ var init_peer_office = __esm({
|
|
|
28676
28740
|
init_residency_pins();
|
|
28677
28741
|
init_maintenance_desk_pb();
|
|
28678
28742
|
init_subscription_manager();
|
|
28743
|
+
init_shell_contract();
|
|
28679
28744
|
init_replica_follow_controller();
|
|
28680
28745
|
init_replica_follow_desk();
|
|
28681
28746
|
init_local_copy_drop();
|
|
@@ -28872,10 +28937,9 @@ var init_peer_office = __esm({
|
|
|
28872
28937
|
this.#trace,
|
|
28873
28938
|
(session) => this.#readMaintenance.schedule(session, ReadMaintenanceCause.READ_DEBT),
|
|
28874
28939
|
observations,
|
|
28875
|
-
// An interactive peer keeps its thread responsive while watches catch up
|
|
28876
|
-
|
|
28877
|
-
|
|
28878
|
-
} : void 0
|
|
28940
|
+
// An interactive peer keeps its thread responsive while watches catch up: owed re-reads
|
|
28941
|
+
// wait for its drive() turns.
|
|
28942
|
+
this.#interactivePeer
|
|
28879
28943
|
);
|
|
28880
28944
|
this.#application = new ApplicationDesk({
|
|
28881
28945
|
onAdmitted: (session) => {
|
|
@@ -29282,7 +29346,9 @@ var init_peer_office = __esm({
|
|
|
29282
29346
|
* mirrors queue/backoff state.
|
|
29283
29347
|
*/
|
|
29284
29348
|
drive() {
|
|
29285
|
-
|
|
29349
|
+
if (this.#subscriptions.drainOwedTurn()) return 0n;
|
|
29350
|
+
const wake = this.#maintenance.drive();
|
|
29351
|
+
return this.#subscriptions.owesRefresh ? 0n : wake;
|
|
29286
29352
|
}
|
|
29287
29353
|
/**
|
|
29288
29354
|
* Carry one exact maintenance demand through a durable host continuation.
|
|
@@ -30243,6 +30309,7 @@ var init_peer_office = __esm({
|
|
|
30243
30309
|
};
|
|
30244
30310
|
peerOffice = {
|
|
30245
30311
|
open(kernel, credentials, profile, observations, custodyStorage, peerDeskStore) {
|
|
30312
|
+
assertShellContract();
|
|
30246
30313
|
return new PeerOffice(kernel, credentials, profile, observations, custodyStorage, peerDeskStore);
|
|
30247
30314
|
},
|
|
30248
30315
|
Peer: PeerOffice
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.113.
|
|
3
|
+
"version": "0.113.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
32
32
|
"@bufbuild/protobuf": "^2.13.0",
|
|
33
|
-
"@githolon/dsl": "^0.113.
|
|
33
|
+
"@githolon/dsl": "^0.113.3",
|
|
34
34
|
"fast-xml-parser": "5.10.1",
|
|
35
35
|
"isomorphic-git": "^1.38.4",
|
|
36
36
|
"tsx": "^4.19.2",
|