@base44/functions-compiler 0.1.0 → 0.1.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.
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Compile an app's functions into the final Cloudflare Workers shards.
3
+ *
4
+ * The loop is: plan the partition, compile each shard, measure it, and halve any
5
+ * shard whose module is over a ceiling before anything is uploaded. Ported from
6
+ * `_build_shard_with_split` in apper's `cloudflare_wfp_runtime.py`.
7
+ *
8
+ * That function also splits on two exceptions, and neither is a trigger here.
9
+ * The bundler's 413 is its HTTP request-body cap — a property of the shard's
10
+ * packed SOURCE going over the wire, not of the module coming out, and there is
11
+ * no request to reject locally. Cloudflare's 10027 is a real Worker limit, but
12
+ * it is the same 64 MiB `workerRawSizeBreach` already computes from the bytes in
13
+ * hand, so reaching it from a rejected upload is a failsafe, not the design.
14
+ * Measuring is the design, and it happens here.
15
+ *
16
+ * Unlike the compiler's own `bundleApp`, this refuses a partial result. A module
17
+ * missing a handler is not a smaller success, it is a broken app.
18
+ */
19
+ import { bundleApp } from "../bundler.js";
20
+ import { planFreshShards } from "./plan.js";
21
+ import { judgeBundleSize } from "./size.js";
22
+ /** Shards compile independently; bound how many esbuild runs are in flight so
23
+ * peak memory does not scale with the app's function count. */
24
+ const MAX_PARALLEL_SHARDS = 4;
25
+ /**
26
+ * Compile every function into shards, or fail the whole build.
27
+ *
28
+ * Succeeds only when each declared function appears exactly once across the
29
+ * shards and every one of them compiled.
30
+ */
31
+ export async function compileFunctionShards(functions, policy, options = {}) {
32
+ const duplicate = firstDuplicate(functions.map((fn) => fn.name));
33
+ if (duplicate) {
34
+ return fail([{ message: `Duplicate function name "${duplicate}".` }]);
35
+ }
36
+ const byName = new Map(functions.map((fn) => [fn.name, fn]));
37
+ const plan = planFreshShards(functions.map((fn) => fn.name), policy);
38
+ const groups = plan.map((names) => names.map((name) => byName.get(name)));
39
+ const outcomes = await mapWithConcurrency(groups, MAX_PARALLEL_SHARDS, (group) => buildWithSplit(group, policy, options));
40
+ const failures = outcomes.flatMap((o) => (o.ok ? [] : o.failures));
41
+ if (failures.length > 0)
42
+ return fail(failures);
43
+ const shards = outcomes
44
+ .flatMap((o) => (o.ok ? o.shards : []))
45
+ .map((shard, index) => ({ ...shard, index }));
46
+ const missing = assertEveryFunctionPlacedOnce(functions, shards);
47
+ if (missing.length > 0)
48
+ return fail(missing);
49
+ return { ok: true, shards };
50
+ }
51
+ /** Compile one planned group, halving it when its module is over a ceiling. The
52
+ * verdict comes from the bytes, so nothing is uploaded to discover it. */
53
+ async function buildWithSplit(group, policy, options) {
54
+ const response = await bundleApp({ functions: group, ...options });
55
+ const compileFailures = response.functions
56
+ .filter((fn) => !fn.ok)
57
+ .map((fn) => ({
58
+ function: fn.name,
59
+ message: `Function "${fn.name}" failed to compile.`,
60
+ errors: fn.ok ? undefined : fn.errors,
61
+ }));
62
+ // A partial module is what the service ships and a whole-app build must not:
63
+ // the peers compiled, but the app is missing a handler.
64
+ if (compileFailures.length > 0)
65
+ return { ok: false, failures: compileFailures };
66
+ if (!response.ok) {
67
+ return fail([{ message: "The combined build produced no module." }]);
68
+ }
69
+ const verdict = await judgeBundleSize(response.module, policy.gzipCapBytes);
70
+ if (!verdict.breach) {
71
+ return {
72
+ ok: true,
73
+ shards: [shardOf(group, response.module, response.main_module, verdict)],
74
+ };
75
+ }
76
+ if (group.length === 1) {
77
+ // Splitting is exhausted: one function's module alone is over the ceiling.
78
+ return {
79
+ ok: false,
80
+ failures: [{ function: group[0].name, message: verdict.breach }],
81
+ };
82
+ }
83
+ const mid = Math.floor(group.length / 2);
84
+ const halves = await Promise.all([
85
+ buildWithSplit(group.slice(0, mid), policy, options),
86
+ buildWithSplit(group.slice(mid), policy, options),
87
+ ]);
88
+ const halfFailures = halves.flatMap((h) => (h.ok ? [] : h.failures));
89
+ if (halfFailures.length > 0)
90
+ return { ok: false, failures: halfFailures };
91
+ return { ok: true, shards: halves.flatMap((h) => (h.ok ? h.shards : [])) };
92
+ }
93
+ function shardOf(group, module, mainModule, verdict) {
94
+ return {
95
+ functions: group.map((fn) => fn.name),
96
+ module,
97
+ mainModule,
98
+ rawBytes: verdict.rawBytes,
99
+ gzipBytes: verdict.gzipBytes,
100
+ };
101
+ }
102
+ /** Every declared function must land in exactly one emitted shard. A name that
103
+ * vanished, or turned up twice after a split, would deploy a broken app. */
104
+ function assertEveryFunctionPlacedOnce(functions, shards) {
105
+ const placed = new Map();
106
+ for (const shard of shards) {
107
+ for (const name of shard.functions) {
108
+ placed.set(name, (placed.get(name) ?? 0) + 1);
109
+ }
110
+ }
111
+ const failures = [];
112
+ for (const fn of functions) {
113
+ const count = placed.get(fn.name) ?? 0;
114
+ if (count !== 1) {
115
+ failures.push({
116
+ function: fn.name,
117
+ message: `Function "${fn.name}" appears in ${count} shards; expected exactly 1.`,
118
+ });
119
+ }
120
+ }
121
+ for (const name of placed.keys()) {
122
+ if (!functions.some((fn) => fn.name === name)) {
123
+ failures.push({
124
+ function: name,
125
+ message: `Shard holds unknown function "${name}".`,
126
+ });
127
+ }
128
+ }
129
+ return failures;
130
+ }
131
+ function firstDuplicate(names) {
132
+ const seen = new Set();
133
+ for (const name of names) {
134
+ if (seen.has(name))
135
+ return name;
136
+ seen.add(name);
137
+ }
138
+ return null;
139
+ }
140
+ function fail(failures) {
141
+ return { ok: false, failures };
142
+ }
143
+ /** Bounded concurrency, input order preserved. */
144
+ async function mapWithConcurrency(items, limit, fn) {
145
+ const results = new Array(items.length);
146
+ let cursor = 0;
147
+ const worker = async () => {
148
+ while (cursor < items.length) {
149
+ const index = cursor++;
150
+ results[index] = await fn(items[index]);
151
+ }
152
+ };
153
+ await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
154
+ return results;
155
+ }
156
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/shards/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Which functions go in which shard, for a build with no previous deploy to
3
+ * reuse. Ported from apper's `shard_planning.py` (`target_shard_count`,
4
+ * `full_repartition`) and the capacity refusal in `deploy_app`.
5
+ *
6
+ * Only the fresh path crosses over. Incremental reuse needs the previous
7
+ * deployment map, and the per-app shard-size ratchet is state written across
8
+ * deploys; both stay with the service.
9
+ */
10
+ /** Everything the planner is allowed to know. It reads no settings and no
11
+ * entitlements — the caller resolves these and passes them in. */
12
+ export interface ShardPolicy {
13
+ /** Functions packed into one shard. May be lower than `globalShardSize` when
14
+ * the caller carries a ratcheted override. */
15
+ shardSize: number;
16
+ /** The size capacity is judged at. A lowered `shardSize` changes packing only
17
+ * and must never lock an app out of deploying. */
18
+ globalShardSize: number;
19
+ maxShards: number;
20
+ /** Compressed ceiling for one shard's module, in bytes. */
21
+ gzipCapBytes: number;
22
+ }
23
+ export declare class ShardCapacityError extends Error {
24
+ constructor(message: string);
25
+ }
26
+ /**
27
+ * How many shards the desired set needs. `maxShards === 1` — sharding off — is
28
+ * always one shard whatever the function count: the whole app bundles into a
29
+ * single Worker, which is the legacy per-app behaviour. Going through the
30
+ * division would trip the capacity check for a flag-off app.
31
+ */
32
+ export declare function targetShardCount(functionCount: number, shardSize: number, maxShards: number): number;
33
+ /**
34
+ * Refuse a set the product cannot hold. Judged at the GLOBAL shard size: a
35
+ * ratcheted-down `shardSize` affects packing only, so judging at it would lock
36
+ * a recovered app out of deploys. The resulting plan may therefore hold more
37
+ * shards than `maxShards` — bounded by the function count, which is no more
38
+ * Workers than the legacy per-function topology used. Do not "tidy" this into a
39
+ * check on the final shard count.
40
+ */
41
+ export declare function assertWithinCapacity(functionCount: number, policy: ShardPolicy): void;
42
+ /**
43
+ * The fresh partition, as a list of shards holding function names.
44
+ *
45
+ * A single planned shard keeps the caller's order; a multi-shard plan sorts by
46
+ * name before chunking. The two differ in apper and the difference is load
47
+ * bearing — function order inside a combined module changes the emitted bytes,
48
+ * so normalising them would be a byte change wearing a cleanup's clothes.
49
+ */
50
+ export declare function planFreshShards(names: string[], policy: ShardPolicy): string[][];
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Which functions go in which shard, for a build with no previous deploy to
3
+ * reuse. Ported from apper's `shard_planning.py` (`target_shard_count`,
4
+ * `full_repartition`) and the capacity refusal in `deploy_app`.
5
+ *
6
+ * Only the fresh path crosses over. Incremental reuse needs the previous
7
+ * deployment map, and the per-app shard-size ratchet is state written across
8
+ * deploys; both stay with the service.
9
+ */
10
+ export class ShardCapacityError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "ShardCapacityError";
14
+ }
15
+ }
16
+ /** The three counts have to be whole numbers of at least one. A zero or
17
+ * negative `shardSize` made the chunking loop below never advance — it hung
18
+ * rather than refusing, where the Python raises on the same input. */
19
+ function assertUsablePolicy(policy) {
20
+ for (const field of ["shardSize", "globalShardSize", "maxShards"]) {
21
+ const value = policy[field];
22
+ if (!Number.isInteger(value) || value < 1) {
23
+ throw new Error(`ShardPolicy.${field} must be an integer of at least 1, got ${value}`);
24
+ }
25
+ }
26
+ }
27
+ function ceilDiv(a, b) {
28
+ return Math.ceil(a / b);
29
+ }
30
+ /**
31
+ * How many shards the desired set needs. `maxShards === 1` — sharding off — is
32
+ * always one shard whatever the function count: the whole app bundles into a
33
+ * single Worker, which is the legacy per-app behaviour. Going through the
34
+ * division would trip the capacity check for a flag-off app.
35
+ */
36
+ export function targetShardCount(functionCount, shardSize, maxShards) {
37
+ if (maxShards === 1)
38
+ return 1;
39
+ return ceilDiv(functionCount, shardSize);
40
+ }
41
+ /**
42
+ * Refuse a set the product cannot hold. Judged at the GLOBAL shard size: a
43
+ * ratcheted-down `shardSize` affects packing only, so judging at it would lock
44
+ * a recovered app out of deploys. The resulting plan may therefore hold more
45
+ * shards than `maxShards` — bounded by the function count, which is no more
46
+ * Workers than the legacy per-function topology used. Do not "tidy" this into a
47
+ * check on the final shard count.
48
+ */
49
+ export function assertWithinCapacity(functionCount, policy) {
50
+ const needed = targetShardCount(functionCount, policy.globalShardSize, policy.maxShards);
51
+ if (needed > policy.maxShards) {
52
+ throw new ShardCapacityError(`App has ${functionCount} functions — over the per-app Worker capacity of ` +
53
+ `${policy.globalShardSize * policy.maxShards} ` +
54
+ `(${policy.maxShards} shards × ${policy.globalShardSize}).`);
55
+ }
56
+ }
57
+ /**
58
+ * The fresh partition, as a list of shards holding function names.
59
+ *
60
+ * A single planned shard keeps the caller's order; a multi-shard plan sorts by
61
+ * name before chunking. The two differ in apper and the difference is load
62
+ * bearing — function order inside a combined module changes the emitted bytes,
63
+ * so normalising them would be a byte change wearing a cleanup's clothes.
64
+ */
65
+ export function planFreshShards(names, policy) {
66
+ assertUsablePolicy(policy);
67
+ assertWithinCapacity(names.length, policy);
68
+ const target = targetShardCount(names.length, policy.shardSize, policy.maxShards);
69
+ if (target <= 1)
70
+ return [[...names]];
71
+ const sorted = [...names].sort();
72
+ const shards = [];
73
+ for (let i = 0; i < sorted.length; i += policy.shardSize) {
74
+ shards.push(sorted.slice(i, i + policy.shardSize));
75
+ }
76
+ return shards;
77
+ }
78
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/shards/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgBH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;uEAEuE;AACvE,SAAS,kBAAkB,CAAC,MAAmB;IAC7C,KAAK,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,iBAAiB,EAAE,WAAW,CAAU,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,KAAK,0CAA0C,KAAK,EAAE,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,CAAS,EAAE,CAAS;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,aAAqB,EACrB,SAAiB,EACjB,SAAiB;IAEjB,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAClC,aAAqB,EACrB,MAAmB;IAEnB,MAAM,MAAM,GAAG,gBAAgB,CAC7B,aAAa,EACb,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,SAAS,CACjB,CAAC;IACF,IAAI,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,kBAAkB,CAC1B,WAAW,aAAa,mDAAmD;YACzE,GAAG,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,SAAS,GAAG;YAC/C,IAAI,MAAM,CAAC,SAAS,aAAa,MAAM,CAAC,eAAe,IAAI,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAe,EACf,MAAmB;IAEnB,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,gBAAgB,CAC7B,KAAK,CAAC,MAAM,EACZ,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,SAAS,CACjB,CAAC;IACF,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * How large a compiled Worker module is, and whether Cloudflare will take it.
3
+ *
4
+ * Ported from apper's `cloudflare_wfp_runtime.py` (`measure_bundle_bytes`,
5
+ * `worker_raw_size_breach`, `worker_gzip_cap_breach`, `judge_bundle_size`).
6
+ * Deciding this before an upload is the whole point: the one real production
7
+ * rejection spent 30 seconds uploading 97 MB to be told the same thing this
8
+ * computes for free.
9
+ */
10
+ /** zlib's default, and the level `wrangler --dry-run` reports — so the number
11
+ * here means the same thing as the one in Cloudflare's docs, in a support
12
+ * thread and on a developer's terminal. It is not a claim about Cloudflare's
13
+ * own server-side compressor, which is unpublished; the safety margin lives in
14
+ * the cap instead. */
15
+ export declare const BUNDLE_GZIP_LEVEL = 6;
16
+ /** Cloudflare's uncompressed per-Worker ceiling, in the units Cloudflare states
17
+ * it in. Taken from a real 10027 in production, which reads verbatim: "Your
18
+ * Worker exceeded the uncompressed size limit of 64 MiB." Decimal 64_000_000
19
+ * would refuse 3 MiB early for no reason. */
20
+ export declare const WORKER_RAW_SIZE_CEILING_BYTES: number;
21
+ export interface BundleSize {
22
+ rawBytes: number;
23
+ gzipBytes: number;
24
+ }
25
+ export interface SizeVerdict extends BundleSize {
26
+ /** Why the module is over a ceiling, or `null` when it is within both. */
27
+ breach: string | null;
28
+ }
29
+ /** `(raw, gzip)` for a compiled module. Compression runs off the event loop:
30
+ * a multi-megabyte gzip is long enough to matter when several shards are in
31
+ * flight. */
32
+ export declare function measureBundleBytes(module: string): Promise<BundleSize>;
33
+ /** Why Cloudflare will reject this module outright, or `null`. The only verdict
34
+ * taken on a number Cloudflare states itself — no estimate, no compression, no
35
+ * headroom to argue about. */
36
+ export declare function workerRawSizeBreach(rawBytes: number): string | null;
37
+ /** Why the module is over the compressed ceiling, or `null`. Our side of the
38
+ * comparison is the estimate, not Cloudflare's number: it compresses
39
+ * server-side with an unpublished algorithm, so level-6 gzip is a proxy for
40
+ * the figure it measures. The cap carries the margin. */
41
+ export declare function workerGzipCapBreach(gzipBytes: number, gzipCapBytes: number): string | null;
42
+ /** Measure a module and say whether it breaches either ceiling. Never throws:
43
+ * what a breach costs depends on whether the caller can re-partition, and only
44
+ * the caller knows that. */
45
+ export declare function judgeBundleSize(module: string, gzipCapBytes: number): Promise<SizeVerdict>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * How large a compiled Worker module is, and whether Cloudflare will take it.
3
+ *
4
+ * Ported from apper's `cloudflare_wfp_runtime.py` (`measure_bundle_bytes`,
5
+ * `worker_raw_size_breach`, `worker_gzip_cap_breach`, `judge_bundle_size`).
6
+ * Deciding this before an upload is the whole point: the one real production
7
+ * rejection spent 30 seconds uploading 97 MB to be told the same thing this
8
+ * computes for free.
9
+ */
10
+ import { promisify } from "node:util";
11
+ import { gzip } from "node:zlib";
12
+ const gzipAsync = promisify(gzip);
13
+ /** zlib's default, and the level `wrangler --dry-run` reports — so the number
14
+ * here means the same thing as the one in Cloudflare's docs, in a support
15
+ * thread and on a developer's terminal. It is not a claim about Cloudflare's
16
+ * own server-side compressor, which is unpublished; the safety margin lives in
17
+ * the cap instead. */
18
+ export const BUNDLE_GZIP_LEVEL = 6;
19
+ /** Cloudflare's uncompressed per-Worker ceiling, in the units Cloudflare states
20
+ * it in. Taken from a real 10027 in production, which reads verbatim: "Your
21
+ * Worker exceeded the uncompressed size limit of 64 MiB." Decimal 64_000_000
22
+ * would refuse 3 MiB early for no reason. */
23
+ export const WORKER_RAW_SIZE_CEILING_BYTES = 64 * 1024 * 1024;
24
+ /** `(raw, gzip)` for a compiled module. Compression runs off the event loop:
25
+ * a multi-megabyte gzip is long enough to matter when several shards are in
26
+ * flight. */
27
+ export async function measureBundleBytes(module) {
28
+ const raw = Buffer.from(module, "utf8");
29
+ const compressed = await gzipAsync(raw, { level: BUNDLE_GZIP_LEVEL });
30
+ return { rawBytes: raw.byteLength, gzipBytes: compressed.byteLength };
31
+ }
32
+ /** Why Cloudflare will reject this module outright, or `null`. The only verdict
33
+ * taken on a number Cloudflare states itself — no estimate, no compression, no
34
+ * headroom to argue about. */
35
+ export function workerRawSizeBreach(rawBytes) {
36
+ if (rawBytes > WORKER_RAW_SIZE_CEILING_BYTES) {
37
+ return (`bundled module is ${rawBytes} bytes uncompressed, over Cloudflare's ` +
38
+ `${WORKER_RAW_SIZE_CEILING_BYTES}-byte (64 MiB) per-Worker ceiling`);
39
+ }
40
+ return null;
41
+ }
42
+ /** Why the module is over the compressed ceiling, or `null`. Our side of the
43
+ * comparison is the estimate, not Cloudflare's number: it compresses
44
+ * server-side with an unpublished algorithm, so level-6 gzip is a proxy for
45
+ * the figure it measures. The cap carries the margin. */
46
+ export function workerGzipCapBreach(gzipBytes, gzipCapBytes) {
47
+ if (gzipBytes > gzipCapBytes) {
48
+ return (`bundled module is ${gzipBytes} bytes gzipped (level ${BUNDLE_GZIP_LEVEL}), ` +
49
+ `over the ${gzipCapBytes}-byte cap for a Cloudflare Worker script`);
50
+ }
51
+ return null;
52
+ }
53
+ /** Measure a module and say whether it breaches either ceiling. Never throws:
54
+ * what a breach costs depends on whether the caller can re-partition, and only
55
+ * the caller knows that. */
56
+ export async function judgeBundleSize(module, gzipCapBytes) {
57
+ const { rawBytes, gzipBytes } = await measureBundleBytes(module);
58
+ // Uncompressed first: it is the exact one, so when both are over it is the
59
+ // verdict worth reporting.
60
+ const breach = workerRawSizeBreach(rawBytes) ??
61
+ workerGzipCapBreach(gzipBytes, gzipCapBytes);
62
+ return { rawBytes, gzipBytes, breach };
63
+ }
64
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","sourceRoot":"","sources":["../../../src/shards/size.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;;;uBAIuB;AACvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;8CAG8C;AAC9C,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAY9D;;cAEc;AACd,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACtE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;AACxE,CAAC;AAED;;+BAE+B;AAC/B,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,IAAI,QAAQ,GAAG,6BAA6B,EAAE,CAAC;QAC7C,OAAO,CACL,qBAAqB,QAAQ,yCAAyC;YACtE,GAAG,6BAA6B,mCAAmC,CACpE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;0DAG0D;AAC1D,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,YAAoB;IAEpB,IAAI,SAAS,GAAG,YAAY,EAAE,CAAC;QAC7B,OAAO,CACL,qBAAqB,SAAS,yBAAyB,iBAAiB,KAAK;YAC7E,YAAY,YAAY,0CAA0C,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;6BAE6B;AAC7B,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,YAAoB;IAEpB,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjE,2EAA2E;IAC3E,2BAA2B;IAC3B,MAAM,MAAM,GACV,mBAAmB,CAAC,QAAQ,CAAC;QAC7B,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * This package's version, as a literal.
3
+ *
4
+ * It goes into every compiled shard's banner, which means it is part of the
5
+ * emitted bytes and therefore part of a deployed version's identity. Reading it
6
+ * from `package.json` at runtime cannot work: a host that bundles this module
7
+ * into an artifact of its own — which the CLI does — ships no `package.json`
8
+ * beside it, and the read silently degraded to "unknown", so the same functions
9
+ * compiled to different bytes in the CLI and in the service.
10
+ *
11
+ * A literal resolves in every host. `version.test.ts` fails the build if it
12
+ * drifts from `package.json`, so bumping the package still means editing two
13
+ * files but cannot mean forgetting one.
14
+ */
15
+ export declare const COMPILER_VERSION = "0.1.2";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This package's version, as a literal.
3
+ *
4
+ * It goes into every compiled shard's banner, which means it is part of the
5
+ * emitted bytes and therefore part of a deployed version's identity. Reading it
6
+ * from `package.json` at runtime cannot work: a host that bundles this module
7
+ * into an artifact of its own — which the CLI does — ships no `package.json`
8
+ * beside it, and the read silently degraded to "unknown", so the same functions
9
+ * compiled to different bytes in the CLI and in the service.
10
+ *
11
+ * A literal resolves in every host. `version.test.ts` fails the build if it
12
+ * drifts from `package.json`, so bumping the package still means editing two
13
+ * files but cannot mean forgetting one.
14
+ */
15
+ export const COMPILER_VERSION = "0.1.2";
16
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC"}
@@ -10,6 +10,8 @@ export declare const ACTIVATION_FILENAME = "__base44_activation.mjs";
10
10
  export interface PreparedWorker {
11
11
  entry: string;
12
12
  files: Record<string, string>;
13
+ /** Prepended verbatim to the compiled module. Only the app path sets it. */
14
+ banner?: string;
13
15
  }
14
16
  export declare function workerRuntimeFiles(): Record<string, string>;
15
17
  /** Shared console-patching prelude injected into every generated Worker entry.
@@ -17,9 +19,6 @@ export declare function workerRuntimeFiles(): Record<string, string>;
17
19
  export declare const CONSOLE_PATCH: string;
18
20
  /** Assemble a single Deno function into a bundle-ready Worker. */
19
21
  export declare function prepareFunction(entry: string, files: Record<string, string>, postResponseTelemetry?: boolean, runtimeSecrets?: boolean): Promise<PreparedWorker>;
20
- /** One app function paired with the stable key its files and diagnostics are
21
- * namespaced under (`fn_<index>`). The index is the function's original
22
- * position so attribution stays correct across an exclude-and-rebuild. */
23
22
  export interface AppFunctionEntry {
24
23
  index: number;
25
24
  fn: AppFunctionInput;
@@ -7,7 +7,9 @@
7
7
  import { readFileSync } from "node:fs";
8
8
  import { DenoCompatError } from "./errors.js";
9
9
  import { RUNTIME_CONTEXT_SPECIFIER } from "./esbuild/runtime-context-virtual.js";
10
+ import { ASCII_ESCAPE, CAPTURE_PATCH, INVOCATION_LOGS_PATCH, } from "./invocation-logs.js";
10
11
  import { TELEMETRY_PATCH, TELEMETRY_STORE_FIELDS } from "./telemetry.js";
12
+ import { COMPILER_VERSION } from "./version.js";
11
13
  // Pre-built by scripts/build-shim.ts; regenerate it after changing the shim.
12
14
  // Read LAZILY, not at module load: build-shim.ts transitively imports this
13
15
  // module through the esbuild plugins, and on a fresh checkout dist/ doesn't
@@ -58,7 +60,9 @@ export const CONSOLE_PATCH = [
58
60
  // by per-app bundles, where one script serves every function and log queries
59
61
  // need per-function attribution. `secrets` and `workerEnv` reference the
60
62
  // request's authoritative Worker env binding.
61
- "const _b44Wrap = (lvl, a) => { const _c = _b44Context() ?? {}; _b44Orig({ _b44_env: _c.env ?? 'preview', ...(_c.fn ? { _b44_function: _c.fn } : {}), level: lvl, message: _b44Fmt(a) }); };",
63
+ ASCII_ESCAPE,
64
+ CAPTURE_PATCH,
65
+ "const _b44Wrap = (lvl, a) => { const _c = _b44Context() ?? {}; const _m = _b44Fmt(a); _b44Capture(_c, lvl, _m); _b44Orig({ _b44_env: _c.env ?? 'preview', ...(_c.fn ? { _b44_function: _c.fn } : {}), level: lvl, message: _m }); };",
62
66
  "console.log = (...a) => _b44Wrap('info', a);",
63
67
  "console.info = (...a) => _b44Wrap('info', a);",
64
68
  "console.warn = (...a) => _b44Wrap('warn', a);",
@@ -102,6 +106,30 @@ export async function prepareFunction(entry, files, postResponseTelemetry = fals
102
106
  },
103
107
  };
104
108
  }
109
+ /** One app function paired with the stable key its files and diagnostics are
110
+ * namespaced under (`fn_<index>`). The index is the function's original
111
+ * position so attribution stays correct across an exclude-and-rebuild. */
112
+ /** Bumped only when the payload's shape changes, never for a new field. */
113
+ const BANNER_FORMAT = 1;
114
+ /** The bundle's self-description, as its first line: `//!b44:<format> <json>`.
115
+ * A fixed sentinel so `head -1` finds it and a reader can version the format,
116
+ * and JSON so it parses in one call. Before this, a compiled module named its
117
+ * functions only as scattered `registerLazy` literals in minified output.
118
+ *
119
+ * Nothing volatile belongs in here. A version's identity is the hash of these
120
+ * bytes, so a timestamp, a build id or anything else that moves on its own
121
+ * would re-mint a version for code that did not change; the app id would make
122
+ * the same functions compile differently per app; the shard's position would
123
+ * make two identical shards differ. Names are sorted for the same reason — the
124
+ * module below is assembled in caller order, this line is not. */
125
+ function buildBanner(entries, telemetry, runtimeSecrets) {
126
+ return `//!b44:${BANNER_FORMAT} ${JSON.stringify({
127
+ functions: entries.map(({ fn }) => fn.name).sort(),
128
+ telemetry,
129
+ runtimeSecrets,
130
+ compiler: COMPILER_VERSION,
131
+ })}`;
132
+ }
105
133
  /** Assemble the whole app into ONE bundle-ready Worker: every function's files
106
134
  * namespaced under `fn_<index>/`, one shared shim, and a router that routes by
107
135
  * function name. A single compile resolves and DEDUPES npm deps across all
@@ -128,7 +156,11 @@ export function prepareApp(entries, postResponseTelemetry = false, runtimeSecret
128
156
  return wrapper;
129
157
  });
130
158
  files[ENTRY_FILENAME] = buildAppEntrySource(moduleFiles, postResponseTelemetry, runtimeSecrets);
131
- return { entry: ENTRY_FILENAME, files };
159
+ return {
160
+ entry: ENTRY_FILENAME,
161
+ files,
162
+ banner: buildBanner(entries, postResponseTelemetry, runtimeSecrets),
163
+ };
132
164
  }
133
165
  // Activation prelude for runtime-secrets bundles: gate on the encrypted
134
166
  // handshake BEFORE any user module is imported (so a needs-activation response
@@ -208,9 +240,9 @@ function buildAppEntrySource(functionModules, telemetry, runtimeSecrets = false)
208
240
  const moduleImports = functionModules
209
241
  .map((file) => `import "./${file}";`)
210
242
  .join("\n");
211
- const handlerExpr = telemetry
243
+ const handlerExpr = `_b44AttachInvocationLogs(${telemetry
212
244
  ? "_b44AttachTelemetry(await handler(request, info))"
213
- : "await handler(request, info)";
245
+ : "await handler(request, info)"})`;
214
246
  const returnExpr = runtimeSecrets
215
247
  ? `withoutActivationSignal(${handlerExpr})`
216
248
  : handlerExpr;
@@ -221,6 +253,7 @@ import { installStaticEgressFetch, resolveHandler } from "./${SHIM_FILENAME}";${
221
253
  ${moduleImports}
222
254
 
223
255
  ${CONSOLE_PATCH}
256
+ ${INVOCATION_LOGS_PATCH}
224
257
  // Static egress reads workerEnv from the active request store. Install it
225
258
  // before telemetry so telemetry remains the outermost fetch wrapper.
226
259
  installStaticEgressFetch();
@@ -230,7 +263,7 @@ export default {
230
263
  async fetch(request, env, ctx) {
231
264
  const _b44Env = (request.headers.get('base44-functions-version') ?? '') === 'prod' ? 'prod' : 'preview';
232
265
  const functionName = request.headers.get("Base44-Function-Name");
233
- return _b44Run({ env: _b44Env, fn: functionName ?? '', secrets: ${runtimeSecrets ? "process.env" : "env"}, workerEnv: env, waitUntil: (p) => ctx.waitUntil(p)${telemetry ? `, ${TELEMETRY_STORE_FIELDS}` : ""} }, async () => {
266
+ return _b44Run({ env: _b44Env, fn: functionName ?? '', secrets: ${runtimeSecrets ? "process.env" : "env"}, workerEnv: env, waitUntil: (p) => ctx.waitUntil(p), ..._b44CaptureStore(request)${telemetry ? `, ${TELEMETRY_STORE_FIELDS}` : ""} }, async () => {
234
267
  ${runtimeSecrets ? ACTIVATION_GATE : ""} // Each early return below logs through the patch first: per-function log
235
268
  // queries on per-app scripts keep only stamped lines, so a bare return
236
269
  // would leave the failing invocation with no trace in its own logs.
@@ -238,22 +271,22 @@ ${runtimeSecrets ? ACTIVATION_GATE : ""} // Each early return below logs th
238
271
  if (pendingHandler === undefined) {
239
272
  const message = \`No function registered for "\${functionName ?? ""}"\`;
240
273
  console.error(message);
241
- return new Response(message, { status: 404 });
274
+ return _b44AttachInvocationLogs(new Response(message, { status: 404 }));
242
275
  }
243
276
  let handler;
244
277
  try {
245
278
  handler = await pendingHandler;
246
279
  } catch (e) {
247
280
  console.error(\`Function "\${functionName}" failed to initialize:\`, e);
248
- return new Response(
281
+ return _b44AttachInvocationLogs(new Response(
249
282
  \`Function "\${functionName}" failed to initialize: \${e instanceof Error ? e.message : String(e)}\`,
250
283
  { status: 500 },
251
- );
284
+ ));
252
285
  }
253
286
  if (handler === null) {
254
287
  const message = \`Function "\${functionName}" must export default a request handler or call Deno.serve()\`;
255
288
  console.error(message);
256
- return new Response(message, { status: 503 });
289
+ return _b44AttachInvocationLogs(new Response(message, { status: 503 }));
257
290
  }
258
291
  // Real client IP is in the "cf-connecting-ip" header, not this placeholder.
259
292
  const info = {
@@ -266,11 +299,14 @@ ${runtimeSecrets ? ACTIVATION_GATE : ""} // Each early return below logs th
266
299
  // stamped lines (see log_query.event_matches_function). Known gap:
267
300
  // exceptions thrown while a response body streams happen after this
268
301
  // frame returns and cannot be stamped — those crash events are
269
- // dropped from per-function views.
302
+ // dropped from per-function views, and lines logged after the response
303
+ // starts streaming are past the invocation-logs header too.
270
304
  try {
271
305
  return ${returnExpr};
272
306
  } catch (e) {
273
307
  console.error(e);
308
+ const crash = _b44CrashResponse(e);
309
+ if (crash) return crash;
274
310
  throw e;
275
311
  }
276
312
  });
@@ -1 +1 @@
1
- {"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/worker-entry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/worker-entry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACL,YAAY,EACZ,aAAa,EACb,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,+EAA+E;AAC/E,4DAA4D;AAC5D,IAAI,eAAmC,CAAC;AACxC,SAAS,cAAc;IACrB,eAAe,KAAK,YAAY,CAC9B,IAAI,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACjD,MAAM,CACP,CAAC;IACF,OAAO,eAAe,CAAC;AACzB,CAAC;AACD,IAAI,qBAAyC,CAAC;AAC9C,SAAS,oBAAoB;IAC3B,qBAAqB,KAAK,YAAY,CACpC,IAAI,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EACvD,MAAM,CACP,CAAC;IACF,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAG,wBAAwB,CAAC;AACtD,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAC5C,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAC7D,qEAAqE;AACrE,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AASxD,MAAM,UAAU,kBAAkB;IAChC,OAAO,EAAE,CAAC,aAAa,CAAC,EAAE,cAAc,EAAE,EAAE,CAAC;AAC/C,CAAC;AAED;+EAC+E;AAC/E,+EAA+E;AAC/E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,+BAA+B;IAC/B,2LAA2L;IAC3L,0BAA0B;IAC1B,uFAAuF;IACvF,cAAc;IACd,uDAAuD;IACvD,wCAAwC;IACxC,uBAAuB;IACvB,0GAA0G;IAC1G,iFAAiF;IACjF,+BAA+B;IAC/B,sBAAsB;IACtB,OAAO;IACP,iDAAiD;IACjD,qCAAqC;IACrC,IAAI;IACJ,6EAA6E;IAC7E,6EAA6E;IAC7E,yEAAyE;IACzE,8CAA8C;IAC9C,YAAY;IACZ,aAAa;IACb,sOAAsO;IACtO,8CAA8C;IAC9C,+CAA+C;IAC/C,+CAA+C;IAC/C,iDAAiD;IACjD,iDAAiD;IACjD,wEAAwE;IACxE,2EAA2E;IAC3E,uEAAuE;IACvE,yEAAyE;IACzE,sEAAsE;IACtE,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,4EAA4E;IAC5E,yEAAyE;IACzE,iCAAiC;IACjC,yEAAyE;IACzE,yEAAyE;IACzE,qEAAqE;IACrE,wJAAwJ;IACxJ,sEAAsE;IACtE,8EAA8E;IAC9E,8EAA8E;IAC9E,sEAAsE;IACtE,uYAAuY;IACvY,yEAAyE;IACzE,0GAA0G;CAC3G,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,KAA6B,EAC7B,qBAAqB,GAAG,KAAK,EAC7B,cAAc,GAAG,KAAK;IAEtB,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO;QACL,KAAK,EAAE,cAAc;QACrB,KAAK,EAAE;YACL,GAAG,SAAS,CAAC,KAAK,CAAC;YACnB,GAAG,kBAAkB,EAAE;YACvB,GAAG,CAAC,cAAc;gBAChB,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,EAAE,EAAE;gBACnD,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAChC,KAAK,EACL,qBAAqB,EACrB,cAAc,CACf;SACF;KACF,CAAC;AACJ,CAAC;AAED;;2EAE2E;AAC3E,2EAA2E;AAC3E,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB;;;;;;;;;;mEAUmE;AACnE,SAAS,WAAW,CAClB,OAA2B,EAC3B,SAAkB,EAClB,cAAuB;IAEvB,OAAO,UAAU,aAAa,IAAI,IAAI,CAAC,SAAS,CAAC;QAC/C,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE;QAClD,SAAS;QACT,cAAc;QACd,QAAQ,EAAE,gBAAgB;KAC3B,CAAC,EAAE,CAAC;AACP,CAAC;AAOD;;;;;;;uBAOuB;AACvB,MAAM,UAAU,UAAU,CACxB,OAA2B,EAC3B,qBAAqB,GAAG,KAAK,EAC7B,cAAc,GAAG,KAAK;IAEtB,MAAM,KAAK,GAA2B;QACpC,GAAG,kBAAkB,EAAE;QACvB,GAAG,CAAC,cAAc;YAChB,CAAC,CAAC,EAAE,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,EAAE,EAAE;YACnD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;QAChD,yBAAyB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACtE,KAAK,CAAC,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC;QACxC,CAAC;QACD,MAAM,OAAO,GAAG,eAAe,KAAK,MAAM,CAAC;QAC3C,KAAK,CAAC,OAAO,CAAC,GAAG,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1E,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,cAAc,CAAC,GAAG,mBAAmB,CACzC,WAAW,EACX,qBAAqB,EACrB,cAAc,CACf,CAAC;IACF,OAAO;QACL,KAAK,EAAE,cAAc;QACrB,KAAK;QACL,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,qBAAqB,EAAE,cAAc,CAAC;KACpE,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,+EAA+E;AAC/E,8EAA8E;AAC9E,MAAM,eAAe,GAAG;;;CAGvB,CAAC;AAEF,SAAS,gBAAgB,CAAC,cAAuB;IAC/C,OAAO,cAAc;QACnB,CAAC,CAAC,+FAA+F,mBAAmB,IAAI;QACxH,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED;;2EAE2E;AAC3E,SAAS,gBAAgB,CACvB,SAAiB,EACjB,SAAkB,EAClB,cAAc,GAAG,KAAK;IAEtB,MAAM,UAAU,GAAG,KAAK,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IACzD,8EAA8E;IAC9E,8EAA8E;IAC9E,MAAM,WAAW,GAAG,SAAS;QAC3B,CAAC,CAAC,mDAAmD;QACrD,CAAC,CAAC,cAAc;YACd,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,wBAAwB,CAAC;IAC/B,MAAM,UAAU,GAAG,cAAc;QAC/B,CAAC,CAAC,2BAA2B,WAAW,GAAG;QAC3C,CAAC,CAAC,WAAW,CAAC;IAChB,OAAO;;kGAEyF,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC;oEACvE,aAAa,KAAK,gBAAgB,CAAC,cAAc,CAAC;;EAEpH,aAAa;;;;EAIb,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE;;;;;;8CAMY,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,uDAAuD,SAAS,CAAC,CAAC,CAAC,KAAK,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAAE;EACvL,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,0CAA0C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;eAiB5F,UAAU;;;;CAIxB,CAAC;AACF,CAAC;AAED,SAAS,yBAAyB,CAChC,YAAoB,EACpB,SAAiB;IAEjB,MAAM,UAAU,GAAG,KAAK,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IACzD,OAAO;kCACyB,aAAa;;eAEhC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;CACtF,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAC1B,eAAyB,EACzB,SAAkB,EAClB,cAAc,GAAG,KAAK;IAEtB,MAAM,aAAa,GAAG,eAAe;SAClC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,IAAI,IAAI,CAAC;SACpC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,WAAW,GAAG,4BAClB,SAAS;QACP,CAAC,CAAC,mDAAmD;QACrD,CAAC,CAAC,8BACN,GAAG,CAAC;IACJ,MAAM,UAAU,GAAG,cAAc;QAC/B,CAAC,CAAC,2BAA2B,WAAW,GAAG;QAC3C,CAAC,CAAC,WAAW,CAAC;IAChB,OAAO;;kGAEyF,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC;8DAC7E,aAAa,KAAK,gBAAgB,CAAC,cAAc,CAAC;EAC9G,aAAa;;EAEb,aAAa;EACb,qBAAqB;;;;EAIrB,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE;;;;;;sEAMoC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,qFAAqF,SAAS,CAAC,CAAC,CAAC,KAAK,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAAE;EAC7O,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCtB,UAAU;;;;;;;;;;CAU1B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,KAA6B;IACrE,2EAA2E;IAC3E,mDAAmD;IACnD,IACE,aAAa,IAAI,KAAK;QACtB,cAAc,IAAI,KAAK;QACvB,oBAAoB,IAAI,KAAK,EAC7B,CAAC;QACD,MAAM,IAAI,eAAe,CACvB,uBAAuB,aAAa,QAAQ,cAAc,QAAQ,oBAAoB,8CAA8C,CACrI,CAAC;IACJ,CAAC;IACD,wEAAwE;IACxE,yEAAyE;IACzE,4EAA4E;IAC5E,0EAA0E;IAC1E,8EAA8E;IAC9E,6EAA6E;IAC7E,6EAA6E;IAC7E,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,mBAAmB,EAAE,CAAC;YAC1E,MAAM,IAAI,eAAe,CACvB,sBAAsB,mBAAmB,uDAAuD,QAAQ,KAAK,CAC9G,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;mEAEmE;AACnE,SAAS,SAAS,CAAC,KAA6B;IAC9C,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,IAAI,aAAa,CAAC,QAAQ,CAAC;YAAE,SAAS;QACtC,GAAG,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,CACL,QAAQ,KAAK,cAAc;QAC3B,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC;QAClC,QAAQ,KAAK,WAAW;QACxB,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAChC,CAAC;AACJ,CAAC"}