aweshare 0.7.0 → 0.7.2
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/README.ai.md +1 -0
- package/README.md +28 -2
- package/apps/agent/dist/config.d.ts +1 -1
- package/apps/agent/dist/config.js +11 -0
- package/apps/agent/dist/config.js.map +1 -1
- package/apps/agent/dist/connection.js +3 -29
- package/apps/agent/dist/connection.js.map +1 -1
- package/apps/agent/dist/hub.d.ts +6 -0
- package/apps/agent/dist/hub.js.map +1 -1
- package/apps/agent/dist/table.d.ts +11 -1
- package/apps/agent/dist/table.js +13 -1
- package/apps/agent/dist/table.js.map +1 -1
- package/apps/consumer/dist/table.d.ts +12 -2
- package/apps/consumer/dist/table.js +13 -2
- package/apps/consumer/dist/table.js.map +1 -1
- package/apps/hub/dist/config.d.ts +1 -1
- package/apps/hub/dist/config.js +11 -0
- package/apps/hub/dist/config.js.map +1 -1
- package/apps/hub/dist/consumer.d.ts +4 -0
- package/apps/hub/dist/consumer.js +13 -1
- package/apps/hub/dist/consumer.js.map +1 -1
- package/apps/hub/dist/db.d.ts +4 -1
- package/apps/hub/dist/db.js +35 -7
- package/apps/hub/dist/db.js.map +1 -1
- package/apps/hub/dist/invites.js +9 -11
- package/apps/hub/dist/invites.js.map +1 -1
- package/apps/hub/dist/local.d.ts +8 -39
- package/apps/hub/dist/local.js +18 -191
- package/apps/hub/dist/local.js.map +1 -1
- package/apps/hub/dist/offerings.d.ts +7 -0
- package/apps/hub/dist/offerings.js +17 -0
- package/apps/hub/dist/offerings.js.map +1 -0
- package/apps/hub/dist/relay.d.ts +114 -0
- package/apps/hub/dist/relay.js +186 -0
- package/apps/hub/dist/relay.js.map +1 -0
- package/apps/hub/dist/table.d.ts +11 -1
- package/apps/hub/dist/table.js +13 -1
- package/apps/hub/dist/table.js.map +1 -1
- package/apps/hub/dist/tunnel.d.ts +9 -82
- package/apps/hub/dist/tunnel.js +43 -197
- package/apps/hub/dist/tunnel.js.map +1 -1
- package/package.json +1 -1
- package/packages/producer-core/dist/catalog.d.ts +23 -1
- package/packages/producer-core/dist/catalog.js +49 -15
- package/packages/producer-core/dist/catalog.js.map +1 -1
- package/packages/producer-core/dist/probe.d.ts +11 -0
- package/packages/producer-core/dist/probe.js +39 -0
- package/packages/producer-core/dist/probe.js.map +1 -1
- package/packages/protocol/dist/errors.d.ts +1 -0
- package/packages/protocol/dist/errors.js +1 -0
- package/packages/protocol/dist/errors.js.map +1 -1
- package/packages/protocol/dist/index.d.ts +1 -0
- package/packages/protocol/dist/index.js +1 -0
- package/packages/protocol/dist/index.js.map +1 -1
- package/packages/protocol/dist/messages.d.ts +5 -0
- package/packages/protocol/dist/messages.js.map +1 -1
- package/packages/protocol/dist/schedule.d.ts +83 -0
- package/packages/protocol/dist/schedule.js +421 -0
- package/packages/protocol/dist/schedule.js.map +1 -0
- package/packages/protocol/dist/time.js +5 -4
- package/packages/protocol/dist/time.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Protocol } from 'aweshare-protocol';
|
|
1
|
+
import { type Protocol, type ShareSchedule } from 'aweshare-protocol';
|
|
2
2
|
/** CLI logins a backend can authenticate with (the producer machine's own login). */
|
|
3
3
|
export type LoginProvider = 'codex';
|
|
4
4
|
export interface Backend {
|
|
@@ -32,6 +32,11 @@ export interface CatalogOffering {
|
|
|
32
32
|
maxConcurrentUsers?: number;
|
|
33
33
|
/** Shared per-alias tokens per UTC day; hub default 1000000, 0 = unlimited. */
|
|
34
34
|
dailyTokens?: number;
|
|
35
|
+
/** Share-time schedule (see aweshare-protocol/schedule): the hub gates
|
|
36
|
+
* admission to this alias by it. Absent when the offering config sets no
|
|
37
|
+
* share-* keys, or when the keys are present but invalid (the offering
|
|
38
|
+
* then does not survive parseCatalog at all). */
|
|
39
|
+
schedule?: ShareSchedule;
|
|
35
40
|
}
|
|
36
41
|
export interface Catalog {
|
|
37
42
|
backends: Backend[];
|
|
@@ -44,6 +49,23 @@ export interface Catalog {
|
|
|
44
49
|
*/
|
|
45
50
|
degradeOn5xx?: boolean;
|
|
46
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate the per-offering cap fields — the same rules the hub enforces on a
|
|
54
|
+
* producer register. The `=== undefined` default is deliberate: an explicit
|
|
55
|
+
* null is a rejected cap, not the default 1. Returns the problem sentences
|
|
56
|
+
* without the offering name (callers prefix it); these exact strings are
|
|
57
|
+
* load-bearing.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseOfferingCaps(raw: {
|
|
60
|
+
maxConcurrencyPerUser?: unknown;
|
|
61
|
+
maxConcurrentUsers?: unknown;
|
|
62
|
+
dailyTokens?: unknown;
|
|
63
|
+
}): {
|
|
64
|
+
maxConcurrencyPerUser: number;
|
|
65
|
+
maxConcurrentUsers?: number;
|
|
66
|
+
dailyTokens?: number;
|
|
67
|
+
problems: string[];
|
|
68
|
+
};
|
|
47
69
|
/**
|
|
48
70
|
* Validate the [[backends]]/[[offerings]] sections of a producer-style config.
|
|
49
71
|
* Shared by the agent (config.toml) and the hub's local producer (the same
|
|
@@ -1,4 +1,30 @@
|
|
|
1
|
-
import { isValidAlias, isValidName, PROTOCOLS } from '../../protocol/dist/index.js';
|
|
1
|
+
import { isValidAlias, isValidName, PROTOCOLS, parseShareSchedule, } from '../../protocol/dist/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate the per-offering cap fields — the same rules the hub enforces on a
|
|
4
|
+
* producer register. The `=== undefined` default is deliberate: an explicit
|
|
5
|
+
* null is a rejected cap, not the default 1. Returns the problem sentences
|
|
6
|
+
* without the offering name (callers prefix it); these exact strings are
|
|
7
|
+
* load-bearing.
|
|
8
|
+
*/
|
|
9
|
+
export function parseOfferingCaps(raw) {
|
|
10
|
+
const problems = [];
|
|
11
|
+
const maxConcurrencyPerUser = raw.maxConcurrencyPerUser === undefined ? 1 : Number(raw.maxConcurrencyPerUser);
|
|
12
|
+
if (!Number.isInteger(maxConcurrencyPerUser) ||
|
|
13
|
+
maxConcurrencyPerUser < 1 ||
|
|
14
|
+
maxConcurrencyPerUser > 64) {
|
|
15
|
+
problems.push('maxConcurrencyPerUser must be an integer 1..64');
|
|
16
|
+
}
|
|
17
|
+
const maxConcurrentUsers = raw.maxConcurrentUsers === undefined ? undefined : Number(raw.maxConcurrentUsers);
|
|
18
|
+
if (maxConcurrentUsers !== undefined &&
|
|
19
|
+
(!Number.isInteger(maxConcurrentUsers) || maxConcurrentUsers < 1 || maxConcurrentUsers > 64)) {
|
|
20
|
+
problems.push('maxConcurrentUsers must be an integer 1..64');
|
|
21
|
+
}
|
|
22
|
+
const dailyTokens = raw.dailyTokens === undefined ? undefined : Number(raw.dailyTokens);
|
|
23
|
+
if (dailyTokens !== undefined && (!Number.isInteger(dailyTokens) || dailyTokens < 0)) {
|
|
24
|
+
problems.push('dailyTokens must be an integer >= 0 (0 = unlimited)');
|
|
25
|
+
}
|
|
26
|
+
return { maxConcurrencyPerUser, maxConcurrentUsers, dailyTokens, problems };
|
|
27
|
+
}
|
|
2
28
|
/**
|
|
3
29
|
* Validate the [[backends]]/[[offerings]] sections of a producer-style config.
|
|
4
30
|
* Shared by the agent (config.toml) and the hub's local producer (the same
|
|
@@ -108,7 +134,6 @@ export function parseCatalog(raw, secrets) {
|
|
|
108
134
|
problems.push(`offering '${alias}': maxConcurrency was renamed to maxConcurrencyPerUser (per-user concurrent requests)`);
|
|
109
135
|
continue;
|
|
110
136
|
}
|
|
111
|
-
const maxConcurrencyPerUser = o.maxConcurrencyPerUser === undefined ? 1 : Number(o.maxConcurrencyPerUser);
|
|
112
137
|
if (!isValidAlias(alias) && !isValidName(alias)) {
|
|
113
138
|
problems.push(`offering: invalid alias '${alias}' (namespace/name or a bare lowercase name; a bare name is prefixed with the producer name)`);
|
|
114
139
|
continue;
|
|
@@ -143,23 +168,31 @@ export function parseCatalog(raw, secrets) {
|
|
|
143
168
|
problems.push(`offering '${alias}': upstreamModel is required (the real backend model id)`);
|
|
144
169
|
continue;
|
|
145
170
|
}
|
|
146
|
-
|
|
147
|
-
maxConcurrencyPerUser
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
const caps = parseOfferingCaps({
|
|
172
|
+
maxConcurrencyPerUser: o.maxConcurrencyPerUser,
|
|
173
|
+
maxConcurrentUsers: o.maxConcurrentUsers,
|
|
174
|
+
dailyTokens: o.dailyTokens,
|
|
175
|
+
});
|
|
176
|
+
for (const problem of caps.problems) {
|
|
177
|
+
problems.push(`offering '${alias}': ${problem}`);
|
|
151
178
|
}
|
|
152
|
-
|
|
153
|
-
if (maxConcurrentUsers !== undefined &&
|
|
154
|
-
(!Number.isInteger(maxConcurrentUsers) || maxConcurrentUsers < 1 || maxConcurrentUsers > 64)) {
|
|
155
|
-
problems.push(`offering '${alias}': maxConcurrentUsers must be an integer 1..64`);
|
|
179
|
+
if (caps.problems.length > 0)
|
|
156
180
|
continue;
|
|
181
|
+
const { maxConcurrencyPerUser, maxConcurrentUsers, dailyTokens } = caps;
|
|
182
|
+
// The share schedule parses against the same rules on both this catalog
|
|
183
|
+
// (agent config.toml, hub local-producer config) and the hub wire, so an
|
|
184
|
+
// accepted offering's schedule never needs re-validating downstream.
|
|
185
|
+
const sched = parseShareSchedule({
|
|
186
|
+
shareWindows: o.shareWindows,
|
|
187
|
+
blockWindows: o.blockWindows,
|
|
188
|
+
shareDays: o.shareDays,
|
|
189
|
+
shareTimezone: o.shareTimezone,
|
|
190
|
+
});
|
|
191
|
+
for (const problem of sched.problems) {
|
|
192
|
+
problems.push(`offering '${alias}': ${problem}`);
|
|
157
193
|
}
|
|
158
|
-
|
|
159
|
-
if (dailyTokens !== undefined && (!Number.isInteger(dailyTokens) || dailyTokens < 0)) {
|
|
160
|
-
problems.push(`offering '${alias}': dailyTokens must be an integer >= 0 (0 = unlimited)`);
|
|
194
|
+
if (sched.problems.length > 0)
|
|
161
195
|
continue;
|
|
162
|
-
}
|
|
163
196
|
for (const backend of backendList) {
|
|
164
197
|
offerings.push({
|
|
165
198
|
alias,
|
|
@@ -168,6 +201,7 @@ export function parseCatalog(raw, secrets) {
|
|
|
168
201
|
maxConcurrencyPerUser,
|
|
169
202
|
maxConcurrentUsers,
|
|
170
203
|
dailyTokens,
|
|
204
|
+
schedule: sched.schedule ?? undefined,
|
|
171
205
|
});
|
|
172
206
|
}
|
|
173
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { Logger } from 'pino';
|
|
1
2
|
import type { ResolvedBackend } from './adapters.js';
|
|
3
|
+
import { type HealthGate } from './health.js';
|
|
2
4
|
export declare function probeTarget(backend: ResolvedBackend): {
|
|
3
5
|
url: string;
|
|
4
6
|
headers: Record<string, string>;
|
|
@@ -13,3 +15,12 @@ export declare function probeBody(model: string, protocol?: 'openai' | 'anthropi
|
|
|
13
15
|
* word 'ping' one turn at a time does, which the budget's error message
|
|
14
16
|
* names so the denial is never mysterious. */
|
|
15
17
|
export declare function isProbeBody(body: Record<string, unknown>, protocol: 'openai' | 'anthropic' | 'responses'): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Probe every degraded backend once. A probe must name a real model id — an
|
|
20
|
+
* upstream that validates model ids answers 4xx to a fake and a recovered
|
|
21
|
+
* backend stays stuck degraded. `force` skips the probe backoff (operator
|
|
22
|
+
* recovery pass); failed probes back off exponentially inside the HealthGate.
|
|
23
|
+
*/
|
|
24
|
+
export declare function probeDegradedBackends(backends: Iterable<ResolvedBackend>, health: Pick<HealthGate, 'isDegraded' | 'probeNotBeforeMs' | 'record'>, log: Logger, modelFor: (backend: ResolvedBackend) => string | undefined, options?: {
|
|
25
|
+
force?: boolean;
|
|
26
|
+
}): Promise<void>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { readCodexCredentials } from './credentials.js';
|
|
2
|
+
import { classifyStatus, logHealthTransition } from './health.js';
|
|
3
|
+
import { fetchUpstream } from './proxy.js';
|
|
2
4
|
export function probeTarget(backend) {
|
|
3
5
|
const base = backend.baseUrl.replace(/\/+$/, '');
|
|
4
6
|
const path = backend.protocol === 'anthropic'
|
|
@@ -91,4 +93,41 @@ export function isProbeBody(body, protocol) {
|
|
|
91
93
|
message.content === 'ping' &&
|
|
92
94
|
body.max_tokens === 1);
|
|
93
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Probe every degraded backend once. A probe must name a real model id — an
|
|
98
|
+
* upstream that validates model ids answers 4xx to a fake and a recovered
|
|
99
|
+
* backend stays stuck degraded. `force` skips the probe backoff (operator
|
|
100
|
+
* recovery pass); failed probes back off exponentially inside the HealthGate.
|
|
101
|
+
*/
|
|
102
|
+
export async function probeDegradedBackends(backends, health, log, modelFor, options = {}) {
|
|
103
|
+
const force = options.force ?? false;
|
|
104
|
+
for (const b of backends) {
|
|
105
|
+
if (!health.isDegraded(b.id))
|
|
106
|
+
continue;
|
|
107
|
+
if (!force && Date.now() < health.probeNotBeforeMs(b.id))
|
|
108
|
+
continue;
|
|
109
|
+
const model = modelFor(b);
|
|
110
|
+
if (model === undefined)
|
|
111
|
+
continue; // no offering left on this backend — nothing real to probe with
|
|
112
|
+
try {
|
|
113
|
+
const { url, headers } = probeTarget(b);
|
|
114
|
+
const resp = await fetchUpstream(b, url, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers,
|
|
117
|
+
body: JSON.stringify(probeBody(model, b.protocol, b.login !== undefined)),
|
|
118
|
+
signal: AbortSignal.timeout(10_000),
|
|
119
|
+
});
|
|
120
|
+
const reason = classifyStatus(resp.status);
|
|
121
|
+
logHealthTransition(log, b.id, health.record(b.id, reason === null, reason ?? undefined), reason === null
|
|
122
|
+
? `probe ok (model '${model}')`
|
|
123
|
+
: `probe ${resp.status} (${reason}) — next attempt backs off`);
|
|
124
|
+
// drain to free the socket
|
|
125
|
+
await resp.arrayBuffer().catch(() => undefined);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
health.record(b.id, false, 'NETWORK');
|
|
129
|
+
log.warn(`probe for backend ${b.id} failed: ${err instanceof Error ? err.message : err}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
94
133
|
//# sourceMappingURL=probe.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../src/probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@ export declare const ERROR_CODES: {
|
|
|
17
17
|
readonly TUNNEL_CLOSED: "TUNNEL_CLOSED";
|
|
18
18
|
readonly BACKEND_NOT_FOUND: "BACKEND_NOT_FOUND";
|
|
19
19
|
readonly REQUEST_CANCELED: "REQUEST_CANCELED";
|
|
20
|
+
readonly SHARE_WINDOW_CLOSED: "SHARE_WINDOW_CLOSED";
|
|
20
21
|
readonly WIRE_VERSION_MISMATCH: "WIRE_VERSION_MISMATCH";
|
|
21
22
|
};
|
|
22
23
|
export type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
|
|
@@ -17,6 +17,7 @@ export const ERROR_CODES = {
|
|
|
17
17
|
TUNNEL_CLOSED: 'TUNNEL_CLOSED',
|
|
18
18
|
BACKEND_NOT_FOUND: 'BACKEND_NOT_FOUND',
|
|
19
19
|
REQUEST_CANCELED: 'REQUEST_CANCELED',
|
|
20
|
+
SHARE_WINDOW_CLOSED: 'SHARE_WINDOW_CLOSED',
|
|
20
21
|
WIRE_VERSION_MISMATCH: 'WIRE_VERSION_MISMATCH',
|
|
21
22
|
};
|
|
22
23
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,iBAAiB,EAAE,mBAAmB;IACtC,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;IAC5B,wBAAwB,EAAE,0BAA0B;IACpD,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,gBAAgB;IAChC,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,qBAAqB;IAC1C,cAAc,EAAE,gBAAgB;IAChC,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,gBAAgB,EAAE,kBAAkB;IACpC,qBAAqB,EAAE,uBAAuB;CACtC,CAAA"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,iBAAiB,EAAE,mBAAmB;IACtC,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;IAC5B,wBAAwB,EAAE,0BAA0B;IACpD,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,gBAAgB;IAChC,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,qBAAqB;IAC1C,cAAc,EAAE,gBAAgB;IAChC,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,mBAAmB;IACtC,gBAAgB,EAAE,kBAAkB;IACpC,mBAAmB,EAAE,qBAAqB;IAC1C,qBAAqB,EAAE,uBAAuB;CACtC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ErrorCode } from './errors.js';
|
|
2
|
+
import type { ShareSchedule } from './schedule.js';
|
|
2
3
|
export declare const WIRE_VERSION = 2;
|
|
3
4
|
export type Protocol = 'openai' | 'anthropic' | 'responses';
|
|
4
5
|
export declare const PROTOCOLS: readonly Protocol[];
|
|
@@ -24,6 +25,10 @@ export interface Offering {
|
|
|
24
25
|
maxConcurrentUsers?: number;
|
|
25
26
|
/** Shared per-alias token budget per UTC day; hub default 1000000, 0 = unlimited. */
|
|
26
27
|
dailyTokens?: number;
|
|
28
|
+
/** Share-time schedule, already resolved by the producer config parser
|
|
29
|
+
* (timezone and today/tomorrow frozen into concrete dates); the hub
|
|
30
|
+
* admits requests to this alias per it. Old hubs ignore unknown fields. */
|
|
31
|
+
schedule?: ShareSchedule;
|
|
27
32
|
}
|
|
28
33
|
export type BackendState = 'ok' | 'unstable' | 'degraded';
|
|
29
34
|
export interface BackendStatus {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAQ,eAA0C,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;AAC1E,CAAC;AA6HD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAClC,UAAU;IACV,WAAW;IACX,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,YAAY;IACZ,eAAe;IACf,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAA;AAEF,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAwB,CAAA;AACjC,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share-time scheduling: a producer may limit an offering to wall-clock
|
|
3
|
+
* windows in a named IANA time zone (allow-list, deny-list, or "every day").
|
|
4
|
+
*
|
|
5
|
+
* Design points, load-bearing for every function in this module:
|
|
6
|
+
* - All window/date semantics live on the *schedule timezone's* wall clock
|
|
7
|
+
* ("09:00-17:00" means 09:00 in the schedule tz, not anyone else's), so
|
|
8
|
+
* DST is handled naturally by Intl.DateTimeFormat: the wall time is
|
|
9
|
+
* decomposed per instant, never by arithmetic on UTC offsets.
|
|
10
|
+
* - `today`/`tomorrow` are config-side sugar: parseShareSchedule resolves
|
|
11
|
+
* them into concrete YYYY-MM-DD dates (against opts.now) before anything
|
|
12
|
+
* goes on the wire; validateShareSchedule deliberately rejects them.
|
|
13
|
+
* - Cross-midnight windows (start > end, e.g. 22:00-06:00) belong to their
|
|
14
|
+
* *start day*: the post-midnight tail (00:00-06:00) counts against the
|
|
15
|
+
* previous calendar day's day-matching, so a weekdays-only 22:00-06:00
|
|
16
|
+
* window stays open late Friday night / early Saturday morning but is
|
|
17
|
+
* closed from Saturday 22:00 on.
|
|
18
|
+
*/
|
|
19
|
+
/** Every rendered time shows this zone (no DST); AWESHARE_TIMEZONE overrides. */
|
|
20
|
+
export declare function displayTimezone(): string;
|
|
21
|
+
/** A resolved schedule, as the producer sends it on the wire (no config-only
|
|
22
|
+
* sugar left — 'today'/'tomorrow' became date arrays at parse time). */
|
|
23
|
+
export interface ShareSchedule {
|
|
24
|
+
timezone: string;
|
|
25
|
+
/** null = every calendar day; named buckets or concrete dates. */
|
|
26
|
+
days: 'weekdays' | 'weekend' | string[] | null;
|
|
27
|
+
/** Allow-list of 'HH:MM-HH:MM' windows; null = all day. */
|
|
28
|
+
windows: string[] | null;
|
|
29
|
+
/** Deny-list of 'HH:MM-HH:MM' windows; null = nothing blocked. */
|
|
30
|
+
exclude: string[] | null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Config side: decode the [[offerings]] share-* keys. All four keys absent →
|
|
34
|
+
* no schedule at all (null); any present-but-invalid key fails the offering.
|
|
35
|
+
* The timezone (explicit shareTimezone, else opts.defaultTimezone, else
|
|
36
|
+
* displayTimezone) is resolved and frozen into the schedule here — never
|
|
37
|
+
* left as a problem — because 'today'/'tomorrow' must bake against the very
|
|
38
|
+
* zone the running requests will be gated on.
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseShareSchedule(raw: {
|
|
41
|
+
shareWindows?: unknown;
|
|
42
|
+
blockWindows?: unknown;
|
|
43
|
+
shareDays?: unknown;
|
|
44
|
+
shareTimezone?: unknown;
|
|
45
|
+
}, opts?: {
|
|
46
|
+
now?: Date;
|
|
47
|
+
defaultTimezone?: string;
|
|
48
|
+
}): {
|
|
49
|
+
schedule: ShareSchedule | null;
|
|
50
|
+
problems: string[];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Wire side (hub): validate the *already resolved* shape a producer sent, so
|
|
54
|
+
* the hub only ever evaluates normalized schedules. The config-only words
|
|
55
|
+
* (today/tomorrow/everyday) and every malformed value land as a problem —
|
|
56
|
+
* 'today' is rejected here, exactly as the config side consumes it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function validateShareSchedule(value: unknown): {
|
|
59
|
+
schedule: ShareSchedule | null;
|
|
60
|
+
problems: string[];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Evaluate a schedule at an instant. The day filter is applied per window's
|
|
64
|
+
* start day: a single-day window exists only on matching wall days; the tail
|
|
65
|
+
* of a crossing window needs the PREVIOUS day's match (weekdays 22:00-06:00
|
|
66
|
+
* stays open Friday night, but Saturday's 22:00 is closed because Saturday
|
|
67
|
+
* itself does not match). Deny-list windows are day-agnostic — they block
|
|
68
|
+
* that wall time no matter what day it is.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isShareOpen(schedule: ShareSchedule, at: Date): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The next minute (from `from`'s minute + 1) at which the schedule opens, or
|
|
73
|
+
* null when nothing opens within the next 370 days. The scan is a plain
|
|
74
|
+
* 1-minute walk so DST transitions and crossing windows need no special
|
|
75
|
+
* casing; a date-list pre-filter short-circuits the common hopeless cases
|
|
76
|
+
* (concrete dates already past or beyond the horizon) — which is exactly
|
|
77
|
+
* what an exhaustive walk would answer, only instantly.
|
|
78
|
+
*/
|
|
79
|
+
export declare function nextShareOpen(schedule: ShareSchedule, from: Date): Date | null;
|
|
80
|
+
/** Human rendering: '{days} {windows}', e.g. 'daily 00:00-06:00' or
|
|
81
|
+
* 'weekdays !14:00-18:00'; the tz is appended only when it differs from the
|
|
82
|
+
* viewer's, as '@Asia/Shanghai'. '-' for absent schedules. */
|
|
83
|
+
export declare function formatShareSchedule(schedule: ShareSchedule | null | undefined, viewerTz?: string): string;
|