@requence/service 0.8.5-edge.1206 → 0.8.5-edge.1212
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/build/{chunk-n7ayk1td.js → chunk-6dx6x31h.js} +15 -47
- package/build/{chunk-n7ayk1td.js.map → chunk-6dx6x31h.js.map} +2 -2
- package/build/cli.js +12 -12
- package/build/cli.js.map +2 -2
- package/build/index.js +146 -115
- package/build/index.js.map +2 -2
- package/build/types/service/src/surfaceUi.d.ts +1 -0
- package/build/types/service/src/surfaceUi.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
function __accessProp(key) {
|
|
7
|
-
return this[key];
|
|
8
|
-
}
|
|
9
|
-
var __toESMCache_node;
|
|
10
|
-
var __toESMCache_esm;
|
|
11
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
12
|
-
var canCache = mod != null && typeof mod === "object";
|
|
13
|
-
if (canCache) {
|
|
14
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
15
|
-
var cached = cache.get(mod);
|
|
16
|
-
if (cached)
|
|
17
|
-
return cached;
|
|
18
|
-
}
|
|
19
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
20
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
21
|
-
for (let key of __getOwnPropNames(mod))
|
|
22
|
-
if (!__hasOwnProp.call(to, key))
|
|
23
|
-
__defProp(to, key, {
|
|
24
|
-
get: __accessProp.bind(mod, key),
|
|
25
|
-
enumerable: true
|
|
26
|
-
});
|
|
27
|
-
if (canCache)
|
|
28
|
-
cache.set(mod, to);
|
|
29
|
-
return to;
|
|
30
|
-
};
|
|
31
|
-
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
32
|
-
|
|
33
1
|
// ../helpers/src/utils/obfuscate.ts
|
|
34
2
|
var separator = "";
|
|
35
3
|
var base65Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
|
|
@@ -301,11 +269,11 @@ function buildServiceIdentityHeaders({
|
|
|
301
269
|
}
|
|
302
270
|
|
|
303
271
|
// src/errors.ts
|
|
304
|
-
class
|
|
272
|
+
class RequenceConnectionError2 extends Error {
|
|
305
273
|
}
|
|
306
274
|
var UNREACHABLE_STATUS = new Set([502, 503, 504]);
|
|
307
275
|
|
|
308
|
-
class
|
|
276
|
+
class RequenceUnreachableError2 extends Error {
|
|
309
277
|
status;
|
|
310
278
|
constructor(status, options) {
|
|
311
279
|
super("The requence system is currently not reachable. Please retry later.", options);
|
|
@@ -313,26 +281,26 @@ class RequenceUnreachableError extends Error {
|
|
|
313
281
|
this.name = "RequenceUnreachableError";
|
|
314
282
|
}
|
|
315
283
|
}
|
|
316
|
-
function
|
|
284
|
+
function isUnreachableStatus2(status) {
|
|
317
285
|
return UNREACHABLE_STATUS.has(status);
|
|
318
286
|
}
|
|
319
|
-
function
|
|
320
|
-
if (
|
|
321
|
-
throw new
|
|
287
|
+
function assertReachable2(response) {
|
|
288
|
+
if (isUnreachableStatus2(response.status)) {
|
|
289
|
+
throw new RequenceUnreachableError2(response.status);
|
|
322
290
|
}
|
|
323
291
|
}
|
|
324
|
-
async function
|
|
292
|
+
async function reachableFetch2(input, init) {
|
|
325
293
|
let response;
|
|
326
294
|
try {
|
|
327
295
|
response = await fetch(input, init);
|
|
328
296
|
} catch (error) {
|
|
329
|
-
throw new
|
|
297
|
+
throw new RequenceUnreachableError2(undefined, { cause: error });
|
|
330
298
|
}
|
|
331
|
-
|
|
299
|
+
assertReachable2(response);
|
|
332
300
|
return response;
|
|
333
301
|
}
|
|
334
302
|
|
|
335
|
-
class
|
|
303
|
+
class UITooLargeError2 extends Error {
|
|
336
304
|
path;
|
|
337
305
|
size;
|
|
338
306
|
maxSize;
|
|
@@ -345,7 +313,7 @@ class UITooLargeError extends Error {
|
|
|
345
313
|
}
|
|
346
314
|
}
|
|
347
315
|
|
|
348
|
-
class
|
|
316
|
+
class UnsupportedCapabilityError2 extends Error {
|
|
349
317
|
capabilities;
|
|
350
318
|
constructor(unsupported) {
|
|
351
319
|
super(unsupportedCapabilityMessage(unsupported));
|
|
@@ -354,7 +322,7 @@ class UnsupportedCapabilityError extends Error {
|
|
|
354
322
|
}
|
|
355
323
|
}
|
|
356
324
|
|
|
357
|
-
class
|
|
325
|
+
class PayloadTooLargeError2 extends Error {
|
|
358
326
|
size;
|
|
359
327
|
maxSize;
|
|
360
328
|
constructor(size, maxSize) {
|
|
@@ -365,7 +333,7 @@ class PayloadTooLargeError extends Error {
|
|
|
365
333
|
}
|
|
366
334
|
}
|
|
367
335
|
|
|
368
|
-
export {
|
|
336
|
+
export { obfuscate, deobfuscate, simple_default, buildServiceClientProperties, CAPABILITY_HEADER_KEYS, readRequiredCapabilities, unsupportedCapabilities, buildServiceIdentityHeaders, RequenceConnectionError2, RequenceUnreachableError2, isUnreachableStatus2, assertReachable2, reachableFetch2, UITooLargeError2, UnsupportedCapabilityError2, PayloadTooLargeError2 };
|
|
369
337
|
|
|
370
|
-
//# debugId=
|
|
371
|
-
//# sourceMappingURL=chunk-
|
|
338
|
+
//# debugId=8A4BD9F84E7DE65D64756E2164756E21
|
|
339
|
+
//# sourceMappingURL=chunk-6dx6x31h.js.map
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"// AMQP connection client properties: how a service SDK announces itself to the\n// broker at connect time, and how `ui/backend` reads that announcement back.\n//\n// `connection.start-ok` carries a free-form `client-properties` table that the\n// broker keeps for the life of the connection. That makes it the one metadata\n// channel a wire-format change cannot break: it is present BEFORE the first\n// dispatch, it is broker state rather than an event (a `ui/backend` restart just\n// re-reads it), and old SDKs already send amqplib/pika defaults — so a MISSING\n// `requence_*` field means \"too old\", with nothing to negotiate.\n//\n// Read side: `GET /api/connections?columns=name,user,client_properties`. The\n// join key already exists: a service connects with its own AMQP username, and\n// that username IS `service-<internalName>`, so `user` → service and\n// `requence_service_version` → version.\n//\n// THIS FILE IS THE CONTRACT. The Python SDK mirrors it in\n// `python/requence/client_properties.py`, and `python/tests/\n// test_client_properties.py` asserts the key set against this source. Changing\n// a key is a wire change: both SDKs ship it together.\n\n// The pinned, namespaced property set. Flat strings on purpose: a nested field\n// table inside a broker event header is more decode surface than it is worth.\nexport const CLIENT_PROPERTY_KEYS = {\n libVersion: 'requence_lib_version',\n serviceVersion: 'requence_service_version',\n capabilities: 'requence_capabilities',\n // Author-chosen debugging label. Optional, non-unique, unvalidated —\n // NOTHING may key off or branch on it.\n name: 'requence_name',\n // Marks a developer's local dev-overlay connection. Only the marker travels,\n // never the devKey (which is an access-token value).\n devOverlay: 'requence_dev_overlay',\n // WHICH PROCESS this is. Not a new id: it is the same per-connection uuid the\n // SDK already stamps on every publish (and names its backchannel queue with),\n // announced here so a fleet row and a node run can be joined on it. Named for\n // a connection and not a replica because those are not the same thing across a\n // reconnect — the TS SDK keeps its id, the Python SDK mints a new one.\n connectionId: 'requence_connection_id',\n // How many task slots this process has: the consumer prefetch of its DISPATCH\n // channel. The surface-handler and durable-callback channels each get their\n // own budget of the same number, so this is NOT the replica's whole capacity.\n // Per-connection, so client properties are its one correct home — a copy\n // frozen onto a node update would go stale.\n prefetch: 'requence_prefetch',\n} as const\n\n// The name is author-controlled text and the whole client-properties table\n// travels inside the connection frame, so an unbounded string is a\n// connection-level failure. Capped in both SDKs and truncated AGAIN on read.\nexport const MAX_SERVICE_NAME_LENGTH = 64\nexport const MAX_CAPABILITIES_LENGTH = 512\n\n// Wire capabilities. `wire:json1` is the JSON body encoding every shipped SDK\n// speaks and is the floor that never goes away; each additional codec joins this\n// list as its own token, and the fleet fold below is what tells a dispatch whether\n// it may use it.\nexport const WIRE_JSON_1 = 'wire:json1'\n// The portable msgpack subset in `@requence/helpers/msgpack` (`packWire`). Claimed\n// only by an SDK that can DECODE it on the dispatch wire — a service echoes the\n// codec it was addressed in, so claiming this is a promise about reading, and the\n// reply direction needs no capability of its own.\n//\n// Both SDKs claim it now; the Python counterpart is `requence/wire_codec.py`. The\n// two lists are still per-language on purpose — the fleet fold intersects across\n// replicas, so a language that lags simply pulls its fleets back to JSON instead\n// of needing a special case.\nexport const WIRE_MSGPACK_1 = 'wire:msgpack1'\nexport const SERVICE_WIRE_CAPABILITIES: ReadonlyArray<string> = [\n WIRE_JSON_1,\n WIRE_MSGPACK_1,\n]\n\n// oxlint-disable-next-line no-control-regex\nconst CONTROL_CHARACTERS = /[\\u0000-\\u001f\\u007f]/g\n\nfunction sanitizeLabel(value: string, maxLength: number) {\n return value.replace(CONTROL_CHARACTERS, '').trim().slice(0, maxLength)\n}\n\nexport interface BuildServiceClientPropertiesParams {\n /** `<language>@<version>`, e.g. `javascript@1.2.3`. */\n libVersion: string\n /** The service version this connection consumes, e.g. `v1`. */\n serviceVersion: string\n /**\n * This connection's own uuid — the one it already publishes with. REQUIRED,\n * like `prefetch`: both are known at connect time in every SDK, so a forgetful\n * one should fail to compile rather than announce a replica nothing can join.\n */\n connectionId: string\n /** The dispatch channel's prefetch — this connection's task-slot total. */\n prefetch: number\n /** Optional author-chosen debugging label. */\n name?: string\n devOverlay?: boolean\n capabilities?: ReadonlyArray<string>\n}\n\n// Builds the properties a service SDK passes to its AMQP client on connect (and\n// therefore on every reconnect, since both clients reuse their connection\n// parameters). Absent optional fields are OMITTED, never sent blank.\nexport function buildServiceClientProperties({\n libVersion,\n serviceVersion,\n connectionId,\n prefetch,\n name,\n devOverlay = false,\n capabilities = SERVICE_WIRE_CAPABILITIES,\n}: BuildServiceClientPropertiesParams): Record<string, string> {\n const properties: Record<string, string> = {\n [CLIENT_PROPERTY_KEYS.libVersion]: libVersion,\n [CLIENT_PROPERTY_KEYS.serviceVersion]: serviceVersion,\n [CLIENT_PROPERTY_KEYS.connectionId]: connectionId,\n // Stringified, like every other value here: the table is flat strings on\n // purpose. The read side is what decides whether it is a usable number.\n [CLIENT_PROPERTY_KEYS.prefetch]: String(prefetch),\n [CLIENT_PROPERTY_KEYS.capabilities]: capabilities\n .join(',')\n .slice(0, MAX_CAPABILITIES_LENGTH),\n }\n\n const label = name ? sanitizeLabel(name, MAX_SERVICE_NAME_LENGTH) : ''\n if (label) {\n properties[CLIENT_PROPERTY_KEYS.name] = label\n }\n\n if (devOverlay) {\n properties[CLIENT_PROPERTY_KEYS.devOverlay] = '1'\n }\n\n return properties\n}\n\n// One attached replica, as read back off its connection. Every field is\n// nullable: an SDK too old to announce yields a blank replica, which is exactly\n// the signal the fold below needs.\nexport interface ServiceReplica {\n libVersion: string | null\n serviceVersion: string | null\n capabilities: string[]\n name: string | null\n devOverlay: boolean\n /**\n * Null means NOT ATTRIBUTABLE — an SDK too old to announce. Never a default\n * replica: a made-up id would join a fleet row to node runs that were not its.\n */\n connectionId: string | null\n /**\n * The task-slot TOTAL, or null when this replica announced none. Never\n * defaulted to 1: absence is not evidence, and against a real prefetch of 5 a\n * guessed total renders \"2 of 1\". A null total means \"show the used count\n * alone\".\n */\n prefetch: number | null\n}\n\nconst BLANK_REPLICA: ServiceReplica = {\n libVersion: null,\n serviceVersion: null,\n capabilities: [],\n name: null,\n devOverlay: false,\n connectionId: null,\n prefetch: null,\n}\n\nfunction readString(\n table: Record<string, unknown>,\n key: string,\n): string | null {\n const value = table[key]\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\n// Parses a broker `client_properties` table. Never throws and never trusts the\n// writer: the name and the capability string are re-capped here, so a\n// misbehaving (or malicious) SDK cannot push an unbounded string into the UI.\nexport function readServiceClientProperties(raw: unknown): ServiceReplica {\n if (typeof raw !== 'object' || raw === null) {\n return { ...BLANK_REPLICA }\n }\n\n const table = raw as Record<string, unknown>\n const rawName = readString(table, CLIENT_PROPERTY_KEYS.name)\n const name = rawName ? sanitizeLabel(rawName, MAX_SERVICE_NAME_LENGTH) : null\n\n return {\n libVersion: readString(table, CLIENT_PROPERTY_KEYS.libVersion),\n serviceVersion: readString(table, CLIENT_PROPERTY_KEYS.serviceVersion),\n capabilities: parseCapabilityList(\n readString(table, CLIENT_PROPERTY_KEYS.capabilities),\n ),\n name: name || null,\n devOverlay: readString(table, CLIENT_PROPERTY_KEYS.devOverlay) === '1',\n connectionId: readString(table, CLIENT_PROPERTY_KEYS.connectionId),\n prefetch: readPositiveInteger(\n readString(table, CLIENT_PROPERTY_KEYS.prefetch),\n ),\n }\n}\n\n// A prefetch of 0, a negative, a decimal or a non-number is not a slot total —\n// it is a writer this reader cannot understand, and the only honest answer is\n// \"unknown\". Never 1: see `ServiceReplica.prefetch`.\nfunction readPositiveInteger(raw: string | null): number | null {\n if (!raw || !/^\\d+$/.test(raw)) {\n return null\n }\n const value = Number(raw)\n return Number.isSafeInteger(value) && value > 0 ? value : null\n}\n\n// Caps the whole string BEFORE splitting, so an unbounded writer cannot push an\n// unbounded list through. A token cut in half by that cap simply matches no\n// known capability, which can only ever UNDER-claim — the safe direction.\nfunction parseCapabilityList(raw: string | null): string[] {\n if (!raw) {\n return []\n }\n return [\n ...new Set(\n raw\n .slice(0, MAX_CAPABILITIES_LENGTH)\n .split(',')\n .map((token) => token.trim())\n .filter(Boolean),\n ),\n ]\n}\n\n// The fleet verdict. `libVersion`/`capabilities` are the MINIMUM across every\n// attached replica, because replicas are mixed during a rolling deploy and a\n// verdict that over-claims breaks the one box that cannot honour it.\nexport interface FleetVerdict {\n libVersion: string | null\n capabilities: string[]\n // True when we hold a row for every replica attached to the queue. False\n // means either nothing is attached, or some attached replica is unaccounted\n // for — in both cases the verdict above is deliberately empty.\n complete: boolean\n}\n\n// Leading `major.minor.patch` of the version half of `<language>@<version>`.\n// Null for anything else (`python@dev`, a garbage string), which sorts LOWEST:\n// an unknown build must never win a minimum fold.\nfunction parseLibVersion(libVersion: string): [number, number, number] | null {\n const match = /@(\\d+)\\.(\\d+)\\.(\\d+)/.exec(libVersion)\n if (!match) {\n return null\n }\n return [Number(match[1]), Number(match[2]), Number(match[3])]\n}\n\n// Both SDKs are released from this monorepo at the same version, so comparing\n// only the numeric half is meaningful even across languages — the question is\n// \"what is the oldest build attached\", not \"which language\".\nfunction isLower(candidate: string, current: string) {\n const parsedCandidate = parseLibVersion(candidate)\n const parsedCurrent = parseLibVersion(current)\n\n if (!parsedCandidate) {\n // Two unknowns: pick deterministically so the verdict never flaps.\n return !parsedCurrent ? candidate < current : true\n }\n if (!parsedCurrent) {\n return false\n }\n\n for (let index = 0; index < 3; index++) {\n if (parsedCandidate[index] !== parsedCurrent[index]) {\n return parsedCandidate[index] < parsedCurrent[index]\n }\n }\n return false\n}\n\n// Folds the announced replicas of ONE service version into a single verdict.\n// `attachedCount` is the queue's consumer count (from the queue count monitor):\n// it is what makes a MISSING announcement visible. Fewer rows than consumers\n// means some attached box never announced itself, and the honest answer is\n// \"unknown\" — a wrong fold is worse than no data.\nexport function foldServiceFleet(\n replicas: ReadonlyArray<ServiceReplica>,\n attachedCount: number,\n): FleetVerdict {\n const complete = replicas.length > 0 && replicas.length >= attachedCount\n if (!complete) {\n return { libVersion: null, capabilities: [], complete }\n }\n\n let libVersion: string | null = null\n for (const replica of replicas) {\n if (!replica.libVersion) {\n // One replica too old to announce ⇒ nothing can be claimed for the fleet.\n return { libVersion: null, capabilities: [], complete }\n }\n if (libVersion === null || isLower(replica.libVersion, libVersion)) {\n libVersion = replica.libVersion\n }\n }\n\n const intersection = new Set(replicas[0].capabilities)\n for (const replica of replicas.slice(1)) {\n const declared = new Set(replica.capabilities)\n for (const capability of intersection) {\n if (!declared.has(capability)) {\n intersection.delete(capability)\n }\n }\n }\n\n return {\n libVersion,\n capabilities: [...intersection].sort(),\n complete,\n }\n}\n\n// THE ONE PLACE A CODEC IS CHOSEN, for the whole system.\n//\n// `ui/backend` calls this at task creation and bakes the answer into the compiled\n// tree, so the operator never decides and holds no presence state: it encodes what\n// the tree tells it to, and every receiver reads the content type off the message.\n//\n// Two ways to answer `json`, and both are the safe direction:\n// - the verdict is incomplete (nothing attached, or an attached replica never\n// announced itself) — an unknown fleet is never given a new codec;\n// - the intersection lacks the token — at least one attached replica cannot\n// decode msgpack, and `foldServiceFleet` has already reduced the fleet to what\n// its weakest member can do.\n//\n// The cost of this being frozen at creation is that a long-running continuous task\n// keeps its codec until it is recreated, so the migration completes only as tasks\n// turn over. That is slow, not unsafe.\nexport function wireCodecForFleet(verdict: FleetVerdict): 'json' | 'msgpack' {\n return verdict.complete && verdict.capabilities.includes(WIRE_MSGPACK_1)\n ? 'msgpack'\n : 'json'\n}\n\n// ─── The dispatch direction: what a message REQUIRES of its consumer ────────\n//\n// The fleet fold above answers \"may this dispatch use a capability?\" BEFORE the\n// message is built. `requires` answers the mirror question at the other end:\n// \"did the replica that actually picked this up have it?\" — because a fold is a\n// verdict about the fleet as it was, and a rollback, a scale-up or a wrong\n// verdict can put an incapable box in front of the message anyway.\n//\n// IT IS A HEADER, NEVER A BODY FIELD. The body is precisely the thing an\n// incapable consumer may be unable to decode, so a requirement stated inside it\n// is unreadable exactly when it matters — the same reasoning that put the codec\n// in `content-type`.\n//\n// An SDK too old to know the header ignores it, as it always has: that is a\n// bare unknown header, not an error. So this is insurance for the NEXT\n// capability, not a fix for a rollback under the current one.\nexport const CAPABILITY_HEADER_KEYS = {\n // dispatch → service: the tokens this message needs. Absent when it needs\n // nothing beyond the floor every SDK speaks.\n requires: 'requires',\n // service → operator: this replica cannot satisfy `requires`. Sent by\n // REPUBLISHING to `<exchange>-retry`, never by nacking — a nack cannot modify\n // the message, these are classic queues (so there is no `x-delivery-count`\n // either), and with no counter anywhere the message would requeue forever.\n mismatch: 'capabilityMismatch',\n // operator → service, on a reroute: how many reroutes are left. Named for\n // reroutes and NOT for retries on purpose — it is its own allowance, never the\n // node's `retry` budget, which the template author set aside for real errors.\n // The operator owns the count; see `MAX_CAPABILITY_REROUTES` in its error\n // consumer.\n reroutes: 'capabilityReroutes',\n} as const\n\n// What a dispatch under `codec` needs of the replica that picks it up. `json` is\n// the floor no SDK has ever lacked, so it requires nothing and the header is\n// omitted entirely.\n//\n// For `wire:msgpack1` this buys nothing on its own — `content-type` already\n// carries that requirement and any SDK new enough to read `requires` has the\n// codec. It is stated anyway so the mechanism has exactly one producer, ready\n// for the first capability that is NOT self-describing.\nexport function requiredCapabilitiesForCodec(\n codec: 'json' | 'msgpack',\n): string[] {\n return codec === 'msgpack' ? [WIRE_MSGPACK_1] : []\n}\n\n// The header table for a dispatch, or `{}` when there is nothing to require —\n// spread into the publish, so an empty requirement sends no header at all\n// rather than a blank one.\nexport function buildRequiresHeader(\n capabilities: ReadonlyArray<string>,\n): Record<string, string> {\n if (capabilities.length === 0) {\n return {}\n }\n return {\n [CAPABILITY_HEADER_KEYS.requires]: capabilities\n .join(',')\n .slice(0, MAX_CAPABILITIES_LENGTH),\n }\n}\n\n// Reads `requires` off a message's header table. Never throws and never trusts\n// the writer, exactly like the client-properties read side: an absent, blank or\n// non-string header means \"requires nothing\", which is how every message\n// published before this existed reads.\nexport function readRequiredCapabilities(headers: unknown): string[] {\n if (typeof headers !== 'object' || headers === null) {\n return []\n }\n return parseCapabilityList(\n readString(\n headers as Record<string, unknown>,\n CAPABILITY_HEADER_KEYS.requires,\n ),\n )\n}\n\n// The tokens this consumer cannot satisfy. Anything unrecognised counts as\n// unsupported — an unknown token is a capability from a newer operator, and\n// guessing it is harmless would defeat the whole point of declaring it.\nexport function unsupportedCapabilities(\n required: ReadonlyArray<string>,\n supported: ReadonlyArray<string> = SERVICE_WIRE_CAPABILITIES,\n): string[] {\n const known = new Set(supported)\n return required.filter((token) => !known.has(token))\n}\n\n// The one diagnostic string, so both SDKs report a mismatch identically and the\n// operator can surface it verbatim. Named and deliberate — the point of the\n// whole mechanism is that the failure is this message and never whatever\n// incidental exception the undecodable payload would have produced.\nexport function unsupportedCapabilityMessage(\n unsupported: ReadonlyArray<string>,\n): string {\n return `unsupported wire capability: ${unsupported.join(', ')}`\n}\n\n// ─── The second announcement: per-run identity on the begin message ─────────\n//\n// Mostly the same values as above, sent again — deliberately, because they\n// answer a DIFFERENT question at a different time:\n//\n// - Client properties (above) say \"can this fleet decode msgpack?\". Live broker\n// state, folded to the MINIMUM across replicas, and the only answer available\n// BEFORE dispatch — which is where it must be, since a codec break fails\n// inside the service's own decoder and no reply could warn us.\n// - These headers say \"which build ran THIS node?\". The service stamps them on\n// its `begin` publish, the operator freezes them into the `NODE_START` update,\n// and that row is written once and never re-derived. Exact, not folded: at\n// dispatch time nobody knows which replica will pick the message up, but once\n// it has, only that replica can say who it is.\n//\n// The two can never disagree — both come from the same constants in the same\n// process, through this one file — and neither is ever read to answer the\n// other's question.\n//\n// Sent on `begin` ONLY, not on every reply: one stamp per node execution.\n\n// Bare, un-namespaced names, matching the message headers that already ride\n// alongside them (`taskId`, `index`, `connectionId`, `version`, `epoch`).\n// `libVersion` keeps its historical name — it is the same value it always was.\nexport const IDENTITY_HEADER_KEYS = {\n libVersion: 'libVersion',\n name: 'serviceName',\n capabilities: 'capabilities',\n // READ-ONLY, and the only asymmetry in this dict: every other key here is\n // both built and read, but `buildServiceIdentityHeaders` does NOT emit this\n // one. The base publish header block of both SDKs already stamps\n // `connectionId` on EVERY message, begin included, so emitting it again would\n // write the same value twice into one header table for no gain. It is listed\n // here so the reader picks it up — and so the cross-language key-name parity\n // test covers the name.\n connectionId: 'connectionId',\n // Does THIS run occupy one of the consumer's dispatch prefetch slots — i.e.\n // does its message stay unacked while the work runs? Per run, not per replica.\n // Emitted by the builder (unlike `connectionId`), because it is new.\n holdsSlot: 'holdsSlot',\n} as const\n\n// What ran one node execution. `libVersion` is DISPLAY-ONLY: it may read\n// `javascript@legacy` (see below), so nothing may parse or branch on it — the\n// pre-dispatch capability answer is the fleet fold, never this.\nexport interface ServiceIdentity {\n libVersion: string | null\n name: string | null\n capabilities: string[]\n /** Which process ran it, joinable against `ServiceReplica.connectionId`. */\n connectionId: string | null\n /**\n * Whether this run holds one of that process's task slots. Null — never\n * `false` — when the message carried no flag, because \"holds no slot\" and\n * \"too old to report\" must stay distinguishable.\n */\n holdsSlot: boolean | null\n}\n\nexport interface BuildServiceIdentityHeadersParams {\n libVersion: string\n /**\n * REQUIRED, so a forgetful SDK fails to compile. `!(isGenerator && mode ===\n * 'CONTINUOUS')` at every call site: that one combination acks immediately and\n * frees its slot, every other stays unacked until the work is done.\n */\n holdsSlot: boolean\n name?: string\n capabilities?: ReadonlyArray<string>\n}\n\n// Built by the service, from its own build-time constants. Nothing is looked up,\n// so nothing can be stale or race a lookup.\nexport function buildServiceIdentityHeaders({\n libVersion,\n holdsSlot,\n name,\n capabilities = SERVICE_WIRE_CAPABILITIES,\n}: BuildServiceIdentityHeadersParams): Record<string, string> {\n const headers: Record<string, string> = {\n [IDENTITY_HEADER_KEYS.libVersion]: libVersion,\n // ALWAYS sent, breaking this file's \"absent optional fields are OMITTED\"\n // rule on purpose: omitting `false` would make it indistinguishable from an\n // SDK too old to report, and those two answers are not the same.\n [IDENTITY_HEADER_KEYS.holdsSlot]: holdsSlot ? '1' : '0',\n [IDENTITY_HEADER_KEYS.capabilities]: capabilities\n .join(',')\n .slice(0, MAX_CAPABILITIES_LENGTH),\n }\n\n const label = name ? sanitizeLabel(name, MAX_SERVICE_NAME_LENGTH) : ''\n if (label) {\n headers[IDENTITY_HEADER_KEYS.name] = label\n }\n\n return headers\n}\n\n// `<language>` half of `<language>@<version>`, for the legacy label below. The\n// `@` is required: without it the string makes no language claim at all, and\n// inventing one from a bare token would put a made-up word in the UI.\nfunction libVersionLanguage(libVersion: string): string | null {\n const match = /^([a-z]+)@/i.exec(libVersion.trim())\n return match ? match[1].toLowerCase() : null\n}\n\n// Parses the identity a service stamped on its begin message. Returns null when\n// the message carried none at all — a reference/or node's NODE_START, or the\n// operator's own loopback.\n//\n// THE LEGACY CASE: an SDK from before this existed still sends `libVersion`, but\n// never sent a name or capabilities. Since every current build declares at least\n// `wire:json1`, a MISSING capabilities header is a reliable \"predates this\" —\n// and the version header still names the language, so it reports as\n// `javascript@legacy` / `python@legacy`. That says \"reported before we asked for\n// more\", which is a different thing from \"unknown\".\nexport function readServiceIdentity(raw: unknown): ServiceIdentity | null {\n if (typeof raw !== 'object' || raw === null) {\n return null\n }\n\n const table = raw as Record<string, unknown>\n const libVersion = readString(table, IDENTITY_HEADER_KEYS.libVersion)\n const rawCapabilities = readString(table, IDENTITY_HEADER_KEYS.capabilities)\n\n if (!rawCapabilities) {\n if (!libVersion) {\n return null\n }\n const language = libVersionLanguage(libVersion)\n return {\n libVersion: language ? `${language}@legacy` : 'legacy',\n name: null,\n capabilities: [],\n // Nulls, deliberately, even though such a build does stamp a\n // `connectionId` on its publishes: it announces none in its client\n // properties, so there is no fleet row to join this to. A run that cannot\n // be attributed to a replica is not attributed to one.\n connectionId: null,\n holdsSlot: null,\n }\n }\n\n // Never trust the writer, exactly as on the client-properties read side.\n const rawName = readString(table, IDENTITY_HEADER_KEYS.name)\n const name = rawName ? sanitizeLabel(rawName, MAX_SERVICE_NAME_LENGTH) : ''\n const rawHoldsSlot = readString(table, IDENTITY_HEADER_KEYS.holdsSlot)\n\n return {\n libVersion,\n name: name || null,\n capabilities: parseCapabilityList(rawCapabilities),\n connectionId: readString(table, IDENTITY_HEADER_KEYS.connectionId),\n // Anything that is not one of the two flags reads as \"did not report\",\n // never as `false`.\n holdsSlot:\n rawHoldsSlot === '1' ? true : rawHoldsSlot === '0' ? false : null,\n }\n}\n\n/**\n * WHY a service node got the codec it got.\n *\n * `wireCodecForFleet` answers `json` for several distinct situations that matter\n * very differently in an incident: a service that is simply offline looks nothing\n * like a management API that is down, which in turn looks nothing like a genuine\n * mixed fleet. Recording only the codec makes \"why is this json?\" unanswerable\n * without shell access to the box, so the reason travels beside it.\n *\n * A compact token rather than prose: it is baked into every service node of every\n * task, and the wording belongs to the UI, which can then change without touching\n * the tree or the operator.\n */\n// A literal tuple, so the protocol schemas can build a `z.enum` straight from it\n// and the vocabulary exists in exactly one place.\nexport const WIRE_CODEC_REASON_VALUES = [\n /** msgpack: every attached replica claimed the capability. */\n 'fleet-capable',\n /** The broker's management API is unreachable, so no fleet can be judged. */\n 'presence-unavailable',\n /** Nothing is attached to this service version's queue at all. */\n 'no-replicas',\n /**\n * Something IS consuming the queue that never announced itself. An SDK too old\n * to announce is also too old to decode, so this folds to json — and it is the\n * one reason that looks like a bug but is the design working.\n */\n 'replicas-unaccounted',\n /** A complete fleet, but at least one replica cannot decode msgpack. */\n 'missing-capability',\n] as const\n\nexport type WireCodecReason = (typeof WIRE_CODEC_REASON_VALUES)[number]\n\n/** Named accessors, so call sites read as intent rather than as string literals. */\nexport const WIRE_CODEC_REASONS = {\n fleetCapable: 'fleet-capable',\n presenceUnavailable: 'presence-unavailable',\n noReplicas: 'no-replicas',\n replicasUnaccounted: 'replicas-unaccounted',\n missingCapability: 'missing-capability',\n} as const satisfies Record<string, WireCodecReason>\n\n/**\n * Explains a `json` verdict from the facts the fleet monitor holds.\n *\n * Split from `wireCodecForFleet` rather than folded into it because the codec\n * decision needs only the verdict, while the explanation needs the counts behind\n * it — and the codec must stay trivially checkable.\n */\nexport function wireCodecReason({\n codec,\n presenceAvailable,\n replicaCount,\n consumerCount,\n}: {\n codec: 'json' | 'msgpack'\n presenceAvailable: boolean\n replicaCount: number\n consumerCount: number\n}): WireCodecReason {\n if (codec === 'msgpack') {\n return WIRE_CODEC_REASONS.fleetCapable\n }\n if (!presenceAvailable) {\n return WIRE_CODEC_REASONS.presenceUnavailable\n }\n // Checked before `no-replicas`, so \"nothing announced but something IS\n // consuming\" reports the consumer rather than claiming the service is offline.\n if (replicaCount < consumerCount) {\n return WIRE_CODEC_REASONS.replicasUnaccounted\n }\n if (replicaCount === 0) {\n return WIRE_CODEC_REASONS.noReplicas\n }\n return WIRE_CODEC_REASONS.missingCapability\n}\n",
|
|
10
10
|
"import { unsupportedCapabilityMessage } from '@requence/helpers/protocol'\n\nexport class RequenceConnectionError extends Error {}\n\n// Gateway statuses an ingress/load balancer emits when no healthy backend is\n// available (maintenance window, deploy, cutover). The backend endpoints never\n// return these themselves, so treating them as \"unreachable\" is unambiguous.\nconst UNREACHABLE_STATUS = new Set([502, 503, 504])\n\n/**\n * Signals that the requence system could not be reached — e.g. during a\n * maintenance window or deploy, when the backend is unreachable (connection\n * refused / timeout / DNS failure) or an ingress returns a gateway error\n * (502/503/504). Callers should treat this as transient and retry later.\n */\nexport class RequenceUnreachableError extends Error {\n constructor(\n public readonly status?: number,\n options?: { cause?: unknown },\n ) {\n super(\n 'The requence system is currently not reachable. Please retry later.',\n options,\n )\n this.name = 'RequenceUnreachableError'\n }\n}\n\nexport function isUnreachableStatus(status: number): boolean {\n return UNREACHABLE_STATUS.has(status)\n}\n\n/**\n * Throws a {@link RequenceUnreachableError} when the response carries a gateway\n * status indicating the system is unreachable. Call right after a fetch, before\n * inspecting `response.ok`.\n */\nexport function assertReachable(response: Response): void {\n if (isUnreachableStatus(response.status)) {\n throw new RequenceUnreachableError(response.status)\n }\n}\n\n/**\n * Wraps `fetch` so a transport-level failure (connection refused, DNS failure,\n * timeout) surfaces as a {@link RequenceUnreachableError} instead of a raw\n * TypeError, and gateway statuses (502/503/504) do the same. The returned\n * response is guaranteed not to be a gateway-error response.\n */\nexport async function reachableFetch(\n input: Parameters<typeof fetch>[0],\n init?: Parameters<typeof fetch>[1],\n): Promise<Response> {\n let response: Response\n try {\n response = await fetch(input, init)\n } catch (error) {\n throw new RequenceUnreachableError(undefined, { cause: error })\n }\n assertReachable(response)\n return response\n}\n\n/**\n * A UI component bundle exceeded the hard cap. Thrown by `createUI` at\n * registration: the source travels inline in every first render of its hash, so\n * an oversized bundle is a deploy-time mistake, not a runtime condition.\n */\nexport class UITooLargeError extends Error {\n readonly path: string\n readonly size: number\n readonly maxSize: number\n\n constructor(path: string, size: number, maxSize: number) {\n super(\n `UI component \"${path}\" is ${size} bytes, which exceeds the maximum ` +\n `component size of ${maxSize} bytes. Bundle only the component and its ` +\n `own dependencies — a whole-app bundle travels with every render.`,\n )\n this.name = 'UITooLargeError'\n this.path = path\n this.size = size\n this.maxSize = maxSize\n }\n}\n\n/**\n * The dispatch declared a capability (`requires` header) this build cannot\n * satisfy, so it was refused before its body was ever decoded.\n *\n * A NAMED error on purpose: the point of the `requires` header is that a\n * mismatch reports the missing capability, instead of whatever incidental\n * exception the undecodable payload would otherwise have produced — a bare\n * `SyntaxError` from `JSON.parse` says nothing about why this box was the wrong\n * one. The message travels to the operator, which surfaces it on the node.\n */\nexport class UnsupportedCapabilityError extends Error {\n readonly capabilities: string[]\n\n constructor(unsupported: ReadonlyArray<string>) {\n super(unsupportedCapabilityMessage(unsupported))\n this.name = 'UnsupportedCapabilityError'\n this.capabilities = [...unsupported]\n }\n}\n\nexport class PayloadTooLargeError extends Error {\n readonly size: number\n readonly maxSize: number\n\n constructor(size: number, maxSize: number) {\n super(\n `Message payload is ${size} bytes, which exceeds the maximum message ` +\n `size of ${maxSize} bytes. Reduce the returned value, or offload large ` +\n `data (files/streams) so it travels by reference instead of inline.`,\n )\n this.name = 'PayloadTooLargeError'\n this.size = size\n this.maxSize = maxSize\n }\n}\n"
|
|
11
11
|
],
|
|
12
|
-
"mappings": "
|
|
13
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "8A4BD9F84E7DE65D64756E2164756E21",
|
|
14
14
|
"names": []
|
|
15
15
|
}
|
package/build/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
RequenceUnreachableError,
|
|
4
3
|
deobfuscate,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
simple_default,
|
|
5
|
+
RequenceUnreachableError2,
|
|
6
|
+
reachableFetch2
|
|
7
|
+
} from "./chunk-6dx6x31h.js";
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
10
10
|
import fs from "node:fs";
|
|
@@ -36,12 +36,12 @@ function loadPkgJson() {
|
|
|
36
36
|
async function fetchTypes(url, headers, targetFile, clear = false) {
|
|
37
37
|
let response;
|
|
38
38
|
try {
|
|
39
|
-
response = await
|
|
39
|
+
response = await reachableFetch2(url, {
|
|
40
40
|
method: "GET",
|
|
41
41
|
headers
|
|
42
42
|
});
|
|
43
43
|
} catch (error) {
|
|
44
|
-
if (error instanceof
|
|
44
|
+
if (error instanceof RequenceUnreachableError2) {
|
|
45
45
|
errorExit(error.message);
|
|
46
46
|
}
|
|
47
47
|
throw error;
|
|
@@ -76,7 +76,7 @@ ${text}`;
|
|
|
76
76
|
simple_default.info(`types saved to |${target}|`);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
y.command("generate-types", "generates typescript types", (
|
|
79
|
+
y.command("generate-types", "generates typescript types", (yargs) => yargs.option("access-token", {
|
|
80
80
|
describe: "access token",
|
|
81
81
|
type: "string"
|
|
82
82
|
}).option("dev-token", {
|
|
@@ -95,8 +95,8 @@ y.command("generate-types", "generates typescript types", (yargs2) => yargs2.opt
|
|
|
95
95
|
}), async (argv) => {
|
|
96
96
|
let token = argv.accessToken ?? process.env.REQUENCE_SERVICE_ACCESS_TOKEN ?? process.env.REQUENCE_ACCESS_TOKEN;
|
|
97
97
|
if (!token) {
|
|
98
|
-
const
|
|
99
|
-
token =
|
|
98
|
+
const pkgJson = loadPkgJson();
|
|
99
|
+
token = pkgJson.requence?.service?.accessToken ?? pkgJson.requence?.accessToken;
|
|
100
100
|
}
|
|
101
101
|
if (argv.clear) {
|
|
102
102
|
console.info();
|
|
@@ -116,8 +116,8 @@ in your |package.json| in |requence.accessToken| / |requence.service.accessToken
|
|
|
116
116
|
};
|
|
117
117
|
let devToken = argv.devToken ?? process.env.REQUENCE_SERVICE_DEV_TOKEN ?? process.env.REQUENCE_DEV_TOKEN;
|
|
118
118
|
if (!devToken) {
|
|
119
|
-
const
|
|
120
|
-
devToken =
|
|
119
|
+
const pkgJson = loadPkgJson();
|
|
120
|
+
devToken = pkgJson.requence?.service?.devToken ?? pkgJson.requence?.devToken;
|
|
121
121
|
}
|
|
122
122
|
if (devToken) {
|
|
123
123
|
const devParts = deobfuscate(devToken);
|
|
@@ -159,5 +159,5 @@ in your |package.json| in |requence.accessToken| / |requence.service.accessToken
|
|
|
159
159
|
});
|
|
160
160
|
}).scriptName("requence-service").help("h").demandCommand(1, 1).strict().parse();
|
|
161
161
|
|
|
162
|
-
//# debugId=
|
|
162
|
+
//# debugId=BB920F0485C8B8E264756E2164756E21
|
|
163
163
|
//# sourceMappingURL=cli.js.map
|
package/build/cli.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { deobfuscate } from '@requence/helpers'\nimport logger from '@requence/logger/simple'\nimport { createEventSource } from 'eventsource-client'\nimport yargs from 'yargs'\nimport { hideBin } from 'yargs/helpers'\nimport { z } from 'zod/v4'\n\nimport { RequenceUnreachableError, reachableFetch } from './errors.ts'\n\n// Load .env automatically (Node 20.12+)\nif (typeof process.loadEnvFile === 'function') {\n try {\n process.loadEnvFile()\n } catch {\n // Ignore if .env is missing\n }\n}\n\nconst y = yargs(hideBin(process.argv))\n\nfunction errorExit(title: string, text?: string): never {\n logger.error(title)\n if (text) {\n logger.error(text)\n }\n process.exit(1)\n}\n\nlet pkgJson: any | null\nfunction loadPkgJson() {\n if (!pkgJson) {\n pkgJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'))\n }\n return pkgJson\n}\n\n// Every line the logger writes carries a timestamp, so the caller no longer\n// has to ask for one in watch mode.\nasync function fetchTypes(\n url: string,\n headers: HeadersInit,\n targetFile: string,\n clear = false,\n) {\n let response: Response\n try {\n response = await reachableFetch(url, {\n method: 'GET',\n headers,\n })\n } catch (error) {\n if (error instanceof RequenceUnreachableError) {\n errorExit(error.message)\n }\n throw error\n }\n\n const branchName = response.headers.get('x-branch-name')\n const text = await response.text()\n\n if (!response.ok) {\n errorExit(text)\n }\n\n let header =\n '// Generated by requence-service CLI — DO NOT EDIT.\\n// Changes will be overwritten.\\n\\n'\n\n if (branchName) {\n header += `// !!! types for branch \"${branchName}\" !!!\\n\\n`\n }\n const data = `${header}/* eslint-disable */\\n/* oxlint-disable */\\n/* prettier-ignore */\\n\\n${text}`\n\n fs.writeFileSync(targetFile, data)\n\n if (clear) {\n console.clear()\n }\n\n const target = path.relative(process.cwd(), targetFile)\n\n if (branchName) {\n logger.info(`types for branch |${branchName}| saved to |${target}|`)\n } else {\n logger.info(`types saved to |${target}|`)\n }\n}\n\ny.command(\n 'generate-types',\n 'generates typescript types',\n (yargs) =>\n yargs\n .option('access-token', {\n describe: 'access token',\n type: 'string',\n })\n .option('dev-token', {\n description: 'dev token',\n type: 'string',\n })\n .option('outfile', {\n default: 'requence-env.d.ts',\n })\n .option('outdir', {\n default: '',\n })\n .option('watch', {\n type: 'boolean',\n })\n .option('clear', {\n description:\n 'clear the terminal on watch updates (use --no-clear to disable)',\n type: 'boolean',\n default: true,\n }),\n async (argv) => {\n let token =\n argv.accessToken ??\n process.env.REQUENCE_SERVICE_ACCESS_TOKEN ??\n process.env.REQUENCE_ACCESS_TOKEN\n\n if (!token) {\n const pkgJson = loadPkgJson()\n token =\n pkgJson.requence?.service?.accessToken ?? pkgJson.requence?.accessToken\n }\n\n if (argv.clear) {\n console.info() // newline\n }\n if (!token) {\n errorExit(\n 'No access token found',\n 'You can provide the access token as argument to |requence-service|,\\nas environment variable |REQUENCE_ACCESS_TOKEN| / |REQUENCE_SERVICE_ACCESS_TOKEN| or\\nin your |package.json| in |requence.accessToken| / |requence.service.accessToken|',\n )\n }\n\n const parts = deobfuscate(token)\n if (parts.length !== 3 || parts[0] !== 'service') {\n errorExit('Invalid service key')\n }\n\n const [, connectionString, serverUrl] = parts\n const headers: HeadersInit = {\n Authorization: `Bearer ${connectionString}`,\n }\n let devToken =\n argv.devToken ??\n process.env.REQUENCE_SERVICE_DEV_TOKEN ??\n process.env.REQUENCE_DEV_TOKEN\n\n if (!devToken) {\n const pkgJson = loadPkgJson()\n devToken =\n pkgJson.requence?.service?.devToken ?? pkgJson.requence?.devToken\n }\n\n if (devToken) {\n const devParts = deobfuscate(devToken)\n if (devParts[0] !== 'api') {\n throw new Error(\n 'invalid dev token: please provide a personal access token',\n )\n }\n if (devParts[2] !== parts[2]) {\n throw new Error(\n 'invalid dev token: access token and dev token belong to different requence instances',\n )\n }\n\n headers['x-dev-authorization'] = devParts[1]\n }\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n )\n\n if (!argv.watch) {\n return\n }\n\n if (argv.clear) {\n console.clear()\n }\n logger.info('Watching for type changes…')\n let lastWrite = Date.now()\n const timeSchema = z.coerce.number().int().positive()\n createEventSource({\n method: 'GET',\n url: serverUrl + '/service/watch',\n headers,\n async onMessage({ data }) {\n const timeResult = timeSchema.safeParse(data)\n if (!timeResult.success || timeResult.data < lastWrite) {\n return\n }\n lastWrite = timeResult.data\n if (argv.clear) {\n console.clear()\n }\n logger.info('Regenerating types…')\n\n await fetchTypes(\n serverUrl + '/service/types/typescript',\n headers,\n path.join(argv.outdir || process.cwd(), argv.outfile),\n argv.clear,\n )\n logger.info('Watching for type changes…')\n },\n })\n },\n)\n .scriptName('requence-service')\n .help('h')\n .demandCommand(1, 1)\n .strict()\n .parse()\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;AAEA;AACA;AAIA;AACA;AACA;AACA;AAKA,IAAI,OAAO,QAAQ,gBAAgB,YAAY;AAAA,EAC7C,IAAI;AAAA,IACF,QAAQ,YAAY;AAAA,IACpB,MAAM;AAGV;AAEA,IAAM,IAAI,MAAM,QAAQ,QAAQ,IAAI,CAAC;AAErC,SAAS,SAAS,CAAC,OAAe,MAAsB;AAAA,EACtD,eAAO,MAAM,KAAK;AAAA,EAClB,IAAI,MAAM;AAAA,IACR,eAAO,MAAM,IAAI;AAAA,EACnB;AAAA,EACA,QAAQ,KAAK,CAAC;AAAA;AAGhB,IAAI;AACJ,SAAS,WAAW,GAAG;AAAA,EACrB,IAAI,CAAC,SAAS;AAAA,IACZ,UAAU,KAAK,MAAM,GAAG,aAAa,gBAAgB,OAAO,CAAC;AAAA,EAC/D;AAAA,EACA,OAAO;AAAA;AAKT,eAAe,UAAU,CACvB,KACA,SACA,YACA,QAAQ,OACR;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,WAAW,MAAM,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "BB920F0485C8B8E264756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|