kitcn 0.27.3 → 0.27.4
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/CHANGELOG.md +28 -0
- package/dist/auth/generated/index.d.ts +1 -1
- package/dist/auth/index.d.ts +16 -16
- package/dist/cli.mjs +208 -67
- package/dist/{generated-contract-disabled-D4mw0d-V.d.ts → generated-contract-disabled-SzH57bhp.d.ts} +13 -13
- package/package.json +2 -2
- package/skills/kitcn/references/setup/index.md +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# kitcn
|
|
2
2
|
|
|
3
|
+
## 0.27.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#400](https://github.com/udecode/kitcn/pull/400) [`9963d33`](https://github.com/udecode/kitcn/commit/9963d33048ec532f0a2d9a06bb618486856178b1) Thanks [@MikeyZhang75](https://github.com/MikeyZhang75)! - ## Patches
|
|
8
|
+
|
|
9
|
+
- Speed up `kitcn analyze` by measuring every selected entry in one bundler pass
|
|
10
|
+
instead of one pass per entry: 4.3 s → 0.8 s of bundling on the 24-entry example
|
|
11
|
+
app, with byte-identical `OutMB`. Each entry is still sized as its own
|
|
12
|
+
independently tree-shaken isolate, so the ranking is unchanged.
|
|
13
|
+
- Report the hotspot `DepMB` and `Files` columns for the files that carry weight in
|
|
14
|
+
each entry's isolate. They previously counted every file the bundler parsed,
|
|
15
|
+
including files tree-shaking dropped entirely, which disagreed with the `--details`
|
|
16
|
+
package and input tables directly beneath them. Expect both columns to read lower
|
|
17
|
+
than before for the same code; `OutMB` and `LocMB` are unaffected.
|
|
18
|
+
- Fix `kitcn analyze` crashing with a bundler stack trace when a Convex entry fails
|
|
19
|
+
to build. It now lists the entry under `Failed entries:`, keeps reporting every
|
|
20
|
+
entry that did build, and still exits `1`. This needs esbuild `0.27.7`, which is
|
|
21
|
+
now the minimum.
|
|
22
|
+
- Warn which entries had their `./schema` imports externalized after a build error,
|
|
23
|
+
instead of leaving the default mode silent about approximate dependency sizes. The
|
|
24
|
+
approximation is applied per entry, so one unbuildable schema import no longer
|
|
25
|
+
shrinks the numbers for unrelated functions.
|
|
26
|
+
- Open the interactive analyzer's package and input panes without a second bundle, so
|
|
27
|
+
moving the selection no longer pauses to rebuild.
|
|
28
|
+
- Document the hotspot ranking columns, in `--help` and in the CLI reference, along
|
|
29
|
+
with the `--top-inputs` / `--top-packages` flags.
|
|
30
|
+
|
|
3
31
|
## 0.27.3
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { S as defineAuth, _ as GenericAuthBeforeResult, b as GenericAuthTriggerHandlers, g as BetterAuthOptionsWithoutDatabase, i as getGeneratedAuthDisabledReason, n as GeneratedAuthDisabledReasonKind, r as createDisabledAuthRuntime, t as AuthRuntime, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../../generated-contract-disabled-
|
|
1
|
+
import { S as defineAuth, _ as GenericAuthBeforeResult, b as GenericAuthTriggerHandlers, g as BetterAuthOptionsWithoutDatabase, i as getGeneratedAuthDisabledReason, n as GeneratedAuthDisabledReasonKind, r as createDisabledAuthRuntime, t as AuthRuntime, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../../generated-contract-disabled-SzH57bhp.js";
|
|
2
2
|
export { type AuthRuntime, BetterAuthOptionsWithoutDatabase, type GeneratedAuthDisabledReasonKind, GenericAuthBeforeResult, GenericAuthDefinition, GenericAuthTriggerChange, GenericAuthTriggerHandlers, GenericAuthTriggers, createDisabledAuthRuntime, defineAuth, getGeneratedAuthDisabledReason };
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as QueryCtxWithPreferredOrmQueryTable, n as LookupByIdResultByCtx, t as DocByCtx } from "../query-context-DJONf8X5.js";
|
|
2
2
|
import { t as GetAuth } from "../types-Bf3XQex5.js";
|
|
3
3
|
import { t as GenericCtx } from "../context-utils-DwZ3Cam1.js";
|
|
4
|
-
import { S as defineAuth, _ as GenericAuthBeforeResult, a as AuthFunctions, b as GenericAuthTriggerHandlers, c as createApi, d as deleteOneHandler, f as findManyHandler, g as BetterAuthOptionsWithoutDatabase, h as updateOneHandler, i as getGeneratedAuthDisabledReason, l as createHandler, m as updateManyHandler, n as GeneratedAuthDisabledReasonKind, o as Triggers, p as findOneHandler, r as createDisabledAuthRuntime, s as createClient, t as AuthRuntime, u as deleteManyHandler, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../generated-contract-disabled-
|
|
4
|
+
import { S as defineAuth, _ as GenericAuthBeforeResult, a as AuthFunctions, b as GenericAuthTriggerHandlers, c as createApi, d as deleteOneHandler, f as findManyHandler, g as BetterAuthOptionsWithoutDatabase, h as updateOneHandler, i as getGeneratedAuthDisabledReason, l as createHandler, m as updateManyHandler, n as GeneratedAuthDisabledReasonKind, o as Triggers, p as findOneHandler, r as createDisabledAuthRuntime, s as createClient, t as AuthRuntime, u as deleteManyHandler, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../generated-contract-disabled-SzH57bhp.js";
|
|
5
5
|
import * as convex_values0 from "convex/values";
|
|
6
6
|
import { Infer } from "convex/values";
|
|
7
7
|
import { AuthConfig, DocumentByName, GenericDataModel, GenericMutationCtx, GenericQueryCtx, GenericSchema, PaginationOptions, PaginationResult, SchemaDefinition, TableNamesInDataModel } from "convex/server";
|
|
@@ -111,32 +111,32 @@ type AdapterPaginationOptions = PaginationOptions & {
|
|
|
111
111
|
};
|
|
112
112
|
declare const adapterWhereValidator: convex_values0.VObject<{
|
|
113
113
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
114
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
115
114
|
connector?: "AND" | "OR" | undefined;
|
|
115
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
116
116
|
value: string | number | boolean | string[] | number[] | null;
|
|
117
117
|
field: string;
|
|
118
118
|
}, {
|
|
119
119
|
connector: convex_values0.VUnion<"AND" | "OR" | undefined, [convex_values0.VLiteral<"AND", "required">, convex_values0.VLiteral<"OR", "required">], "optional", never>;
|
|
120
120
|
field: convex_values0.VString<string, "required">;
|
|
121
121
|
mode: convex_values0.VUnion<"sensitive" | "insensitive" | undefined, [convex_values0.VLiteral<"sensitive", "required">, convex_values0.VLiteral<"insensitive", "required">], "optional", never>;
|
|
122
|
-
operator: convex_values0.VUnion<"
|
|
122
|
+
operator: convex_values0.VUnion<"lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined, [convex_values0.VLiteral<"lt", "required">, convex_values0.VLiteral<"lte", "required">, convex_values0.VLiteral<"gt", "required">, convex_values0.VLiteral<"gte", "required">, convex_values0.VLiteral<"eq", "required">, convex_values0.VLiteral<"in", "required">, convex_values0.VLiteral<"not_in", "required">, convex_values0.VLiteral<"ne", "required">, convex_values0.VLiteral<"contains", "required">, convex_values0.VLiteral<"starts_with", "required">, convex_values0.VLiteral<"ends_with", "required">], "optional", never>;
|
|
123
123
|
value: convex_values0.VUnion<string | number | boolean | string[] | number[] | null, [convex_values0.VString<string, "required">, convex_values0.VFloat64<number, "required">, convex_values0.VBoolean<boolean, "required">, convex_values0.VArray<string[], convex_values0.VString<string, "required">, "required">, convex_values0.VArray<number[], convex_values0.VFloat64<number, "required">, "required">, convex_values0.VNull<null, "required">], "required", never>;
|
|
124
|
-
}, "required", "mode" | "value" | "
|
|
124
|
+
}, "required", "mode" | "value" | "connector" | "field" | "operator">;
|
|
125
125
|
declare const adapterArgsValidator: convex_values0.VObject<{
|
|
126
|
-
limit?: number | undefined;
|
|
127
|
-
offset?: number | undefined;
|
|
128
126
|
select?: string[] | undefined;
|
|
129
|
-
sortBy?: {
|
|
130
|
-
direction: "asc" | "desc";
|
|
131
|
-
field: string;
|
|
132
|
-
} | undefined;
|
|
133
127
|
where?: {
|
|
134
128
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
135
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
136
129
|
connector?: "AND" | "OR" | undefined;
|
|
130
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
137
131
|
value: string | number | boolean | string[] | number[] | null;
|
|
138
132
|
field: string;
|
|
139
133
|
}[] | undefined;
|
|
134
|
+
limit?: number | undefined;
|
|
135
|
+
offset?: number | undefined;
|
|
136
|
+
sortBy?: {
|
|
137
|
+
direction: "asc" | "desc";
|
|
138
|
+
field: string;
|
|
139
|
+
} | undefined;
|
|
140
140
|
model: string;
|
|
141
141
|
}, {
|
|
142
142
|
limit: convex_values0.VFloat64<number | undefined, "optional">;
|
|
@@ -152,24 +152,24 @@ declare const adapterArgsValidator: convex_values0.VObject<{
|
|
|
152
152
|
}, "optional", "direction" | "field">;
|
|
153
153
|
where: convex_values0.VArray<{
|
|
154
154
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
155
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
156
155
|
connector?: "AND" | "OR" | undefined;
|
|
156
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
157
157
|
value: string | number | boolean | string[] | number[] | null;
|
|
158
158
|
field: string;
|
|
159
159
|
}[] | undefined, convex_values0.VObject<{
|
|
160
160
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
161
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
162
161
|
connector?: "AND" | "OR" | undefined;
|
|
162
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
163
163
|
value: string | number | boolean | string[] | number[] | null;
|
|
164
164
|
field: string;
|
|
165
165
|
}, {
|
|
166
166
|
connector: convex_values0.VUnion<"AND" | "OR" | undefined, [convex_values0.VLiteral<"AND", "required">, convex_values0.VLiteral<"OR", "required">], "optional", never>;
|
|
167
167
|
field: convex_values0.VString<string, "required">;
|
|
168
168
|
mode: convex_values0.VUnion<"sensitive" | "insensitive" | undefined, [convex_values0.VLiteral<"sensitive", "required">, convex_values0.VLiteral<"insensitive", "required">], "optional", never>;
|
|
169
|
-
operator: convex_values0.VUnion<"
|
|
169
|
+
operator: convex_values0.VUnion<"lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined, [convex_values0.VLiteral<"lt", "required">, convex_values0.VLiteral<"lte", "required">, convex_values0.VLiteral<"gt", "required">, convex_values0.VLiteral<"gte", "required">, convex_values0.VLiteral<"eq", "required">, convex_values0.VLiteral<"in", "required">, convex_values0.VLiteral<"not_in", "required">, convex_values0.VLiteral<"ne", "required">, convex_values0.VLiteral<"contains", "required">, convex_values0.VLiteral<"starts_with", "required">, convex_values0.VLiteral<"ends_with", "required">], "optional", never>;
|
|
170
170
|
value: convex_values0.VUnion<string | number | boolean | string[] | number[] | null, [convex_values0.VString<string, "required">, convex_values0.VFloat64<number, "required">, convex_values0.VBoolean<boolean, "required">, convex_values0.VArray<string[], convex_values0.VString<string, "required">, "required">, convex_values0.VArray<number[], convex_values0.VFloat64<number, "required">, "required">, convex_values0.VNull<null, "required">], "required", never>;
|
|
171
|
-
}, "required", "mode" | "value" | "
|
|
172
|
-
}, "required", "
|
|
171
|
+
}, "required", "mode" | "value" | "connector" | "field" | "operator">, "optional">;
|
|
172
|
+
}, "required", "model" | "select" | "where" | "limit" | "offset" | "sortBy" | "sortBy.direction" | "sortBy.field">;
|
|
173
173
|
declare const hasUniqueFields: (betterAuthSchema: BetterAuthDBSchema, model: string, input: Record<string, any>) => boolean;
|
|
174
174
|
declare const checkUniqueFields: <Schema extends SchemaDefinition<any, any>>(ctx: GenericQueryCtx<GenericDataModel>, schema: Schema, betterAuthSchema: BetterAuthDBSchema, table: string, input: Record<string, any>, doc?: Record<string, any>) => Promise<void>;
|
|
175
175
|
declare const selectFields: <T extends TableNamesInDataModel<GenericDataModel>, D extends DocumentByName<GenericDataModel, T>>(doc: D | null, select?: string[]) => D | null;
|
package/dist/cli.mjs
CHANGED
|
@@ -454,6 +454,13 @@ Modes:
|
|
|
454
454
|
(default) Hotspot analysis (per-function isolate ranking)
|
|
455
455
|
--deploy Deploy analysis (single isolate bundle, Convex-like)
|
|
456
456
|
|
|
457
|
+
Hotspot columns (all describe what the entry actually bundles):
|
|
458
|
+
OutMB Bundled size of the isolate this entry deploys into
|
|
459
|
+
DepMB Source size of the dependency files in that isolate
|
|
460
|
+
LocMB Source size of your own Convex files in that isolate
|
|
461
|
+
Files Files contributing bytes to that isolate
|
|
462
|
+
Fns Convex handlers exported by the entry
|
|
463
|
+
|
|
457
464
|
Flags:
|
|
458
465
|
--details Show extra per-entry/package details
|
|
459
466
|
--input Include top internal inputs in detail output
|
|
@@ -522,13 +529,46 @@ const packageFromInputPath = (inputPath) => {
|
|
|
522
529
|
}
|
|
523
530
|
return "(other)";
|
|
524
531
|
};
|
|
525
|
-
|
|
532
|
+
/** Matches the `out: 'e<index>'` names `createHotspotBuildOptions` assigns. */
|
|
533
|
+
const HOTSPOT_ENTRY_OUTPUT_REGEX = /^out\/e(\d+)\.[^/]+$/;
|
|
534
|
+
const isLocalInputPath = (inputPath) => inputPath.startsWith("convex/") || inputPath.startsWith("example/convex/") || inputPath.includes("/example/convex/");
|
|
535
|
+
/**
|
|
536
|
+
* Hotspot ranks each Convex function by the isolate it deploys into, so every
|
|
537
|
+
* entry needs its own fully tree-shaken closure.
|
|
538
|
+
*
|
|
539
|
+
* esbuild parses each input once per build no matter how many entry points it
|
|
540
|
+
* receives, and with splitting OFF every entry output still carries its own
|
|
541
|
+
* independently tree-shaken closure. Passing the whole entry set to one build
|
|
542
|
+
* therefore keeps per-entry byte counts identical to building each entry alone
|
|
543
|
+
* while reading the shared import graph once.
|
|
544
|
+
*
|
|
545
|
+
* Do not turn on `splitting` here. Shared chunks retain code a lone entry would
|
|
546
|
+
* have dropped, which inflates exactly the number this mode ranks by (measured
|
|
547
|
+
* up to +70% on `example`) and turns dynamic imports into extra outputs that
|
|
548
|
+
* carry an `entryPoint`. `--deploy` already owns the split-bundle view.
|
|
549
|
+
*
|
|
550
|
+
* Each entry is given an explicit output name so its result can be found by
|
|
551
|
+
* position instead of by path. esbuild resolves a symlinked source file to its
|
|
552
|
+
* real path before reporting `output.entryPoint`, so matching that field back
|
|
553
|
+
* against the selected entry would silently lose any entry reached through a
|
|
554
|
+
* symlink. Explicit names also make `foo.ts` and `foo.js` in one directory
|
|
555
|
+
* unable to collide on a single output path.
|
|
556
|
+
*
|
|
557
|
+
* `attributeHotspotBuild` must be given the same `entryPoints` array, since the
|
|
558
|
+
* output name is the entry's index in it.
|
|
559
|
+
*/
|
|
560
|
+
const createHotspotBuildOptions = (entryPoints, projectRoot, externalizeSchema) => ({
|
|
561
|
+
absWorkingDir: projectRoot,
|
|
526
562
|
bundle: true,
|
|
527
|
-
entryPoints:
|
|
563
|
+
entryPoints: entryPoints.map((entryPoint, index) => ({
|
|
564
|
+
in: entryPoint,
|
|
565
|
+
out: `e${index}`
|
|
566
|
+
})),
|
|
528
567
|
external: ["convex", "convex/*"],
|
|
529
568
|
format: "esm",
|
|
530
569
|
logLevel: "silent",
|
|
531
570
|
metafile: true,
|
|
571
|
+
outdir: "out",
|
|
532
572
|
platform: "browser",
|
|
533
573
|
target: ["esnext"],
|
|
534
574
|
conditions: ["convex", "module"],
|
|
@@ -539,42 +579,67 @@ const buildHotspotEntry = (entryPoint, externalizeSchema) => loadEsbuild().build
|
|
|
539
579
|
write: false,
|
|
540
580
|
plugins: externalizeSchema ? [schemaExternalFallbackPlugin] : []
|
|
541
581
|
});
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
582
|
+
/**
|
|
583
|
+
* `allowSchemaFallback` is off for the shared pass on purpose. Externalizing
|
|
584
|
+
* `./schema` removes real weight from every entry that imports it, not just the
|
|
585
|
+
* one that failed: forcing it across `example` moved 25 of 26 rows, one by
|
|
586
|
+
* -98%. Letting the shared pass fail and rebuilding per entry instead keeps the
|
|
587
|
+
* approximation on the entries that actually need it.
|
|
588
|
+
*/
|
|
589
|
+
const buildHotspotBundle = async (entryPoints, projectRoot, allowSchemaFallback) => {
|
|
545
590
|
try {
|
|
546
|
-
|
|
591
|
+
return {
|
|
592
|
+
result: await loadEsbuild().build(createHotspotBuildOptions(entryPoints, projectRoot, false)),
|
|
593
|
+
schemaExternalized: false
|
|
594
|
+
};
|
|
547
595
|
} catch (error) {
|
|
548
|
-
if (!shouldRetryWithSchemaExternalized(error)) throw error;
|
|
549
|
-
|
|
550
|
-
|
|
596
|
+
if (!(allowSchemaFallback && shouldRetryWithSchemaExternalized(error))) throw error;
|
|
597
|
+
return {
|
|
598
|
+
result: await loadEsbuild().build(createHotspotBuildOptions(entryPoints, projectRoot, true)),
|
|
599
|
+
schemaExternalized: true
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
/**
|
|
604
|
+
* Row metrics describe what actually weighs something in the entry's isolate.
|
|
605
|
+
*
|
|
606
|
+
* They count the inputs that emit bytes into that entry's output, which is the
|
|
607
|
+
* same set the `--details` package and input tables below them already report.
|
|
608
|
+
* The build-wide `meta.inputs` cannot answer this: it lists every file esbuild
|
|
609
|
+
* parsed, including ones tree-shaking dropped entirely (534 of 1545 on
|
|
610
|
+
* `example`), and a shared bundle makes it the union across entries rather than
|
|
611
|
+
* one entry's graph. It stays the lookup table for *source* bytes, so `LocMB`
|
|
612
|
+
* and `DepMB` keep measuring source weight rather than post-minify weight.
|
|
613
|
+
*/
|
|
614
|
+
const buildHotspotRow = (params) => {
|
|
615
|
+
const { entryPoint, projectRoot, inputs, output, includeDeepData, schemaExternalized } = params;
|
|
616
|
+
const outputInputEntries = Object.entries(output.inputs ?? {});
|
|
617
|
+
let inputCount = 0;
|
|
618
|
+
let totalInputBytes = 0;
|
|
619
|
+
let localInputBytes = 0;
|
|
620
|
+
for (const [inputPath, value] of outputInputEntries) {
|
|
621
|
+
if ((value.bytesInOutput ?? 0) <= 0) continue;
|
|
622
|
+
inputCount += 1;
|
|
623
|
+
const sourceBytes = inputs[inputPath]?.bytes ?? 0;
|
|
624
|
+
totalInputBytes += sourceBytes;
|
|
625
|
+
if (isLocalInputPath(inputPath)) localInputBytes += sourceBytes;
|
|
551
626
|
}
|
|
552
|
-
const meta = result.metafile;
|
|
553
|
-
if (!meta) throw new Error(`No metafile generated for ${entryPoint}`);
|
|
554
|
-
const output = Object.values(meta.outputs).at(0);
|
|
555
|
-
if (!output) throw new Error(`No output generated for ${entryPoint}`);
|
|
556
|
-
const inputEntries = Object.entries(meta.inputs);
|
|
557
|
-
const totalInputBytes = inputEntries.reduce((sum, [, value]) => sum + (value.bytes ?? 0), 0);
|
|
558
|
-
const isLocalInput = (inputPath) => inputPath.startsWith("convex/") || inputPath.startsWith("example/convex/") || inputPath.includes("/example/convex/");
|
|
559
|
-
const localInputBytes = inputEntries.filter(([inputPath]) => isLocalInput(inputPath)).reduce((sum, [, value]) => sum + (value.bytes ?? 0), 0);
|
|
560
627
|
const row = {
|
|
561
628
|
entry: path.relative(projectRoot, entryPoint),
|
|
562
|
-
inputCount
|
|
629
|
+
inputCount,
|
|
563
630
|
localInputBytes,
|
|
564
631
|
dependencyInputBytes: Math.max(0, totalInputBytes - localInputBytes),
|
|
565
|
-
totalInputBytes,
|
|
566
632
|
outputBytes: output.bytes,
|
|
567
633
|
schemaExternalized
|
|
568
634
|
};
|
|
569
635
|
if (!includeDeepData) return row;
|
|
570
|
-
const
|
|
571
|
-
const outputInputs = Object.entries(output.inputs ?? {}).map(([inputPath, value]) => ({
|
|
636
|
+
const outputInputs = outputInputEntries.map(([inputPath, value]) => ({
|
|
572
637
|
path: inputPath,
|
|
573
638
|
bytesInOutput: value.bytesInOutput ?? 0,
|
|
574
|
-
sourceBytes:
|
|
639
|
+
sourceBytes: inputs[inputPath]?.bytes ?? 0
|
|
575
640
|
})).sort((a, b) => b.bytesInOutput - a.bytesInOutput);
|
|
576
|
-
const inputSet = new Set(
|
|
577
|
-
const importsByInput = Object.fromEntries(
|
|
641
|
+
const inputSet = new Set(outputInputEntries.map(([inputPath]) => inputPath));
|
|
642
|
+
const importsByInput = Object.fromEntries(outputInputEntries.map(([inputPath]) => [inputPath, Array.from(new Set((inputs[inputPath]?.imports ?? []).map((entry) => entry.path).filter((importPath) => typeof importPath === "string" && inputSet.has(importPath))))]));
|
|
578
643
|
return {
|
|
579
644
|
...row,
|
|
580
645
|
deep: {
|
|
@@ -583,6 +648,34 @@ const analyzeHotspotEntry = async (entryPoint, projectRoot, includeDeepData) =>
|
|
|
583
648
|
}
|
|
584
649
|
};
|
|
585
650
|
};
|
|
651
|
+
/**
|
|
652
|
+
* Pairs each entry with its output through the position `createHotspotBuildOptions`
|
|
653
|
+
* encoded in the output name, so `entryPoints` must be the array that built `meta`.
|
|
654
|
+
*/
|
|
655
|
+
const attributeHotspotBuild = (params) => {
|
|
656
|
+
const { entryPoints, projectRoot, meta, includeDeepData, schemaExternalized } = params;
|
|
657
|
+
const inputs = meta.inputs;
|
|
658
|
+
const outputByEntryIndex = /* @__PURE__ */ new Map();
|
|
659
|
+
for (const [outputPath, output] of Object.entries(meta.outputs)) {
|
|
660
|
+
const index = HOTSPOT_ENTRY_OUTPUT_REGEX.exec(outputPath)?.[1];
|
|
661
|
+
if (index === void 0) continue;
|
|
662
|
+
outputByEntryIndex.set(Number(index), output);
|
|
663
|
+
}
|
|
664
|
+
const rowsByEntry = /* @__PURE__ */ new Map();
|
|
665
|
+
for (const [index, entryPoint] of entryPoints.entries()) {
|
|
666
|
+
const output = outputByEntryIndex.get(index);
|
|
667
|
+
if (!output) throw new Error(`esbuild produced no output for ${path.relative(projectRoot, entryPoint)}.`);
|
|
668
|
+
rowsByEntry.set(entryPoint, buildHotspotRow({
|
|
669
|
+
entryPoint,
|
|
670
|
+
includeDeepData,
|
|
671
|
+
inputs,
|
|
672
|
+
output,
|
|
673
|
+
projectRoot,
|
|
674
|
+
schemaExternalized
|
|
675
|
+
}));
|
|
676
|
+
}
|
|
677
|
+
return rowsByEntry;
|
|
678
|
+
};
|
|
586
679
|
const printHotspotTopInputs = (row, options) => {
|
|
587
680
|
if (!row.deep) return;
|
|
588
681
|
const internalInputs = row.deep.outputInputs.filter((input) => input.bytesInOutput > 0 && !isNodeModulesInputPath(input.path));
|
|
@@ -866,37 +959,106 @@ const collectAnalyzeEntrySelection = async (roots, options) => {
|
|
|
866
959
|
};
|
|
867
960
|
const MAX_ANALYZE_CONCURRENCY = 8;
|
|
868
961
|
/**
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
962
|
+
* Only the per-entry recovery sweep still runs multiple builds, so the cap
|
|
963
|
+
* stays low enough to avoid oversubscribing esbuild's worker pool on small
|
|
964
|
+
* machines.
|
|
872
965
|
*/
|
|
873
966
|
const resolveAnalyzeConcurrency = (taskCount) => {
|
|
874
967
|
if (taskCount <= 1) return 1;
|
|
875
968
|
const cpuCount = os.cpus().length || 1;
|
|
876
969
|
return Math.max(1, Math.min(MAX_ANALYZE_CONCURRENCY, cpuCount - 1, taskCount));
|
|
877
970
|
};
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
const
|
|
971
|
+
const toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
972
|
+
const runHotspotBuild = async (entryPoints, projectRoot, includeDeepData, allowSchemaFallback, build) => {
|
|
973
|
+
const { result, schemaExternalized } = await build(entryPoints, projectRoot, allowSchemaFallback);
|
|
974
|
+
const meta = result.metafile;
|
|
975
|
+
if (!meta) throw new Error("esbuild produced no metafile for the hotspot bundle.");
|
|
976
|
+
return attributeHotspotBuild({
|
|
977
|
+
entryPoints,
|
|
978
|
+
includeDeepData,
|
|
979
|
+
meta,
|
|
980
|
+
projectRoot,
|
|
981
|
+
schemaExternalized
|
|
982
|
+
});
|
|
983
|
+
};
|
|
984
|
+
/**
|
|
985
|
+
* Recovery path only. A shared build fails as a unit, so one unbuildable entry
|
|
986
|
+
* would take the whole report down. Rebuilding one entry at a time is the only
|
|
987
|
+
* way to say *which* entry is broken, and it reuses the same build options so
|
|
988
|
+
* surviving rows keep the numbers the shared pass would have produced. It is
|
|
989
|
+
* also where the schema fallback belongs, since here it only degrades the
|
|
990
|
+
* entries that actually need it.
|
|
991
|
+
*
|
|
992
|
+
* Reaching this path needs esbuild >= 0.27.7. Earlier builds threw
|
|
993
|
+
* `SyntaxError: Unexpected end of JSON input` out of esbuild's own stdout
|
|
994
|
+
* handler whenever a `metafile: true` build failed, which is outside any promise
|
|
995
|
+
* this module can catch, so the CLI died before any sweep could report a failed
|
|
996
|
+
* row.
|
|
997
|
+
*/
|
|
998
|
+
const sweepHotspotEntriesIndividually = async (entryPoints, projectRoot, includeDeepData, build) => {
|
|
999
|
+
const results = await mapWithConcurrency(entryPoints, resolveAnalyzeConcurrency(entryPoints.length), async (entryPoint) => {
|
|
881
1000
|
try {
|
|
882
1001
|
return {
|
|
883
|
-
|
|
884
|
-
|
|
1002
|
+
rowsByEntry: await runHotspotBuild([entryPoint], projectRoot, includeDeepData, true, build),
|
|
1003
|
+
failedRows: []
|
|
885
1004
|
};
|
|
886
1005
|
} catch (error) {
|
|
887
1006
|
return {
|
|
888
|
-
|
|
889
|
-
|
|
1007
|
+
rowsByEntry: /* @__PURE__ */ new Map(),
|
|
1008
|
+
failedRows: [{
|
|
1009
|
+
entry: path.relative(projectRoot, entryPoint),
|
|
1010
|
+
error: toErrorMessage(error)
|
|
1011
|
+
}]
|
|
890
1012
|
};
|
|
891
1013
|
}
|
|
892
1014
|
});
|
|
1015
|
+
const rowsByEntry = /* @__PURE__ */ new Map();
|
|
1016
|
+
const failedRows = [];
|
|
1017
|
+
for (const result of results) {
|
|
1018
|
+
for (const [entryPoint, row] of result.rowsByEntry) rowsByEntry.set(entryPoint, row);
|
|
1019
|
+
failedRows.push(...result.failedRows);
|
|
1020
|
+
}
|
|
1021
|
+
return {
|
|
1022
|
+
rowsByEntry,
|
|
1023
|
+
failedRows
|
|
1024
|
+
};
|
|
1025
|
+
};
|
|
1026
|
+
const sweepHotspotEntries = async (entryPoints, projectRoot, includeDeepData, build = buildHotspotBundle) => {
|
|
1027
|
+
if (entryPoints.length === 0) return {
|
|
1028
|
+
rowsByEntry: /* @__PURE__ */ new Map(),
|
|
1029
|
+
failedRows: [],
|
|
1030
|
+
fallbackReason: null
|
|
1031
|
+
};
|
|
1032
|
+
try {
|
|
1033
|
+
return {
|
|
1034
|
+
rowsByEntry: await runHotspotBuild(entryPoints, projectRoot, includeDeepData, false, build),
|
|
1035
|
+
failedRows: [],
|
|
1036
|
+
fallbackReason: null
|
|
1037
|
+
};
|
|
1038
|
+
} catch (error) {
|
|
1039
|
+
return {
|
|
1040
|
+
...await sweepHotspotEntriesIndividually(entryPoints, projectRoot, includeDeepData, build),
|
|
1041
|
+
fallbackReason: firstLine(toErrorMessage(error))
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
const collectHotspotRows = async (roots, options, includeDeepData) => {
|
|
1046
|
+
const { isolateEntries, generatedEntries, entryPoints, handlerExportsByEntry } = await collectAnalyzeEntrySelection(roots, options);
|
|
1047
|
+
const { rowsByEntry, failedRows, fallbackReason } = await sweepHotspotEntries(entryPoints, roots.projectRoot, includeDeepData);
|
|
893
1048
|
return {
|
|
894
1049
|
isolateEntries,
|
|
895
1050
|
generatedEntries,
|
|
896
1051
|
entryPoints,
|
|
897
|
-
successRows:
|
|
898
|
-
|
|
899
|
-
|
|
1052
|
+
successRows: entryPoints.flatMap((entryPoint) => {
|
|
1053
|
+
const row = rowsByEntry.get(entryPoint);
|
|
1054
|
+
if (!row) return [];
|
|
1055
|
+
return [{
|
|
1056
|
+
...row,
|
|
1057
|
+
handlerExports: handlerExportsByEntry.get(entryPoint) ?? []
|
|
1058
|
+
}];
|
|
1059
|
+
}).sort((a, b) => b.outputBytes - a.outputBytes),
|
|
1060
|
+
failedRows,
|
|
1061
|
+
fallbackReason
|
|
900
1062
|
};
|
|
901
1063
|
};
|
|
902
1064
|
const buildPackageImportGraphRows = (row, limit = 12) => {
|
|
@@ -1021,7 +1183,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1021
1183
|
...options,
|
|
1022
1184
|
includeGenerated: state.includeGenerated,
|
|
1023
1185
|
entryPattern: null
|
|
1024
|
-
},
|
|
1186
|
+
}, true);
|
|
1025
1187
|
let visibleRows = sortHotspotRows(filterHotspotRows(snapshot.successRows, state.filterQuery), state.sortKey);
|
|
1026
1188
|
let watcher = null;
|
|
1027
1189
|
let watchTimer = null;
|
|
@@ -1029,7 +1191,6 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1029
1191
|
let refreshQueued = false;
|
|
1030
1192
|
let shouldQuit = false;
|
|
1031
1193
|
let listViewportHeight = 10;
|
|
1032
|
-
const deepRowCache = /* @__PURE__ */ new Map();
|
|
1033
1194
|
const getSelectedEntry = () => visibleRows.at(state.selectedIndex)?.entry ?? null;
|
|
1034
1195
|
const findRowByEntry = (entry) => {
|
|
1035
1196
|
if (!entry) return null;
|
|
@@ -1064,8 +1225,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1064
1225
|
...options,
|
|
1065
1226
|
includeGenerated: state.includeGenerated,
|
|
1066
1227
|
entryPattern: null
|
|
1067
|
-
},
|
|
1068
|
-
deepRowCache.clear();
|
|
1228
|
+
}, true);
|
|
1069
1229
|
syncVisibleRows(preferredEntry);
|
|
1070
1230
|
state = reduceInteractiveState(state, {
|
|
1071
1231
|
type: "setStatus",
|
|
@@ -1147,28 +1307,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1147
1307
|
stdin.setEncoding("utf8");
|
|
1148
1308
|
}
|
|
1149
1309
|
};
|
|
1150
|
-
const
|
|
1151
|
-
if (deepRowCache.has(entry)) return deepRowCache.get(entry) ?? null;
|
|
1152
|
-
const entryPoint = path.join(roots.projectRoot, entry);
|
|
1153
|
-
try {
|
|
1154
|
-
const analyzed = await analyzeHotspotEntry(entryPoint, roots.projectRoot, true);
|
|
1155
|
-
const fallbackHandlers = findRowByEntry(entry)?.handlerExports ?? [];
|
|
1156
|
-
const mergedRow = {
|
|
1157
|
-
...analyzed,
|
|
1158
|
-
handlerExports: snapshot.handlerExportsByEntry.get(entryPoint) ?? fallbackHandlers
|
|
1159
|
-
};
|
|
1160
|
-
deepRowCache.set(entry, mergedRow);
|
|
1161
|
-
return mergedRow;
|
|
1162
|
-
} catch (error) {
|
|
1163
|
-
deepRowCache.set(entry, null);
|
|
1164
|
-
state = reduceInteractiveState(state, {
|
|
1165
|
-
type: "setStatus",
|
|
1166
|
-
message: `Detail load failed for ${entry}: ${firstLine(error instanceof Error ? error.message : String(error))}`
|
|
1167
|
-
});
|
|
1168
|
-
return null;
|
|
1169
|
-
}
|
|
1170
|
-
};
|
|
1171
|
-
const renderInteractive = async () => {
|
|
1310
|
+
const renderInteractive = () => {
|
|
1172
1311
|
const layout = resolveInteractiveLayout(stdout.columns ?? outputWidth, stdout.rows ?? 30);
|
|
1173
1312
|
listViewportHeight = layout.listViewportHeight;
|
|
1174
1313
|
state = reduceInteractiveState(state, {
|
|
@@ -1176,8 +1315,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1176
1315
|
topIndex: fitListViewport(visibleRows.length, state.selectedIndex, layout.listViewportHeight, state.topIndex)
|
|
1177
1316
|
});
|
|
1178
1317
|
const activeEntry = (visibleRows.at(state.selectedIndex) ?? null)?.entry ?? null;
|
|
1179
|
-
|
|
1180
|
-
if (!state.showHelp && activeEntry && state.detailPane !== "handlers") detailRow = await ensureDeepRow(activeEntry);
|
|
1318
|
+
const detailRow = findRowByEntry(activeEntry);
|
|
1181
1319
|
const statusLine = state.statusMessage || "Ready";
|
|
1182
1320
|
const headerLine = `entries=${visibleRows.length}/${snapshot.successRows.length} sort=${sortLabel(state.sortKey)} filter=${state.filterQuery || "∅"} all=${state.includeGenerated ? "on" : "off"} pane=${state.detailPane} watch=${state.watchEnabled ? "on" : "off"}`;
|
|
1183
1321
|
const listLines = (() => {
|
|
@@ -1231,7 +1369,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1231
1369
|
stdin.setEncoding("utf8");
|
|
1232
1370
|
try {
|
|
1233
1371
|
while (!shouldQuit) {
|
|
1234
|
-
|
|
1372
|
+
renderInteractive();
|
|
1235
1373
|
const key = await readKey();
|
|
1236
1374
|
if (key === "" || key === "q") {
|
|
1237
1375
|
shouldQuit = true;
|
|
@@ -1317,7 +1455,7 @@ const runHotspotInteractive = async (roots, options) => {
|
|
|
1317
1455
|
const runHotspotAnalysis = async (roots, options) => {
|
|
1318
1456
|
if (shouldPromptForHotspotPick(options)) return runHotspotInteractive(roots, options);
|
|
1319
1457
|
const includeDeepData = options.details;
|
|
1320
|
-
const { isolateEntries, generatedEntries, entryPoints, successRows, failedRows } = await collectHotspotRows(roots, options, includeDeepData);
|
|
1458
|
+
const { isolateEntries, generatedEntries, entryPoints, successRows, failedRows, fallbackReason } = await collectHotspotRows(roots, options, includeDeepData);
|
|
1321
1459
|
if (entryPoints.length === 0) {
|
|
1322
1460
|
if (options.includeGenerated) console.log("No matching entries found for the provided regex.");
|
|
1323
1461
|
else console.log("No matching Convex handler entries found (files exporting query/mutation/action, including internal variants).");
|
|
@@ -1343,6 +1481,9 @@ const runHotspotAnalysis = async (roots, options) => {
|
|
|
1343
1481
|
const actionRows = successRows;
|
|
1344
1482
|
console.log(bold("Runtime hotspot analysis (least optimized functions)"));
|
|
1345
1483
|
console.log(`isolateEntries=${isolateEntries.length} handlers=${totalHandlers} extraAll=${generatedEntries.length} selected=${entryPoints.length} ok=${successRows.length} failed=${failedRows.length} avg=${formatBytes(outputAverage)}${largest ? ` largest=${largest.entry} (${formatBytes(largest.outputBytes)})` : ""}`);
|
|
1484
|
+
if (fallbackReason) console.log(dim(`note: the shared bundle failed, so entries were rebuilt one at a time: ${fallbackReason}`));
|
|
1485
|
+
const approximateRows = successRows.filter((row) => row.schemaExternalized);
|
|
1486
|
+
if (approximateRows.length > 0) console.log(colorize(`note: schema imports were externalized after a build error for ${approximateRows.length} ${approximateRows.length === 1 ? "entry" : "entries"}; their dependency sizes are approximate (${approximateRows.map((row) => row.entry).join(", ")}).`, ANSI.yellow));
|
|
1346
1487
|
console.log("");
|
|
1347
1488
|
if (actionRows.length > 0) {
|
|
1348
1489
|
console.log(bold("Agent queue (run top-down):"));
|
package/dist/{generated-contract-disabled-D4mw0d-V.d.ts → generated-contract-disabled-SzH57bhp.d.ts}
RENAMED
|
@@ -183,8 +183,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
183
183
|
deleteMany: convex_server0.RegisteredMutation<"internal", {
|
|
184
184
|
input: {
|
|
185
185
|
where?: {
|
|
186
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
187
186
|
connector?: "AND" | "OR" | undefined;
|
|
187
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
188
188
|
value: string | number | boolean | string[] | number[] | null;
|
|
189
189
|
field: string;
|
|
190
190
|
}[] | undefined;
|
|
@@ -212,8 +212,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
212
212
|
deleteOne: convex_server0.RegisteredMutation<"internal", {
|
|
213
213
|
input: {
|
|
214
214
|
where?: {
|
|
215
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
216
215
|
connector?: "AND" | "OR" | undefined;
|
|
216
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
217
217
|
value: string | number | boolean | string[] | number[] | null;
|
|
218
218
|
field: string;
|
|
219
219
|
}[] | undefined;
|
|
@@ -225,19 +225,20 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
225
225
|
}, Promise<Record<string, unknown> | undefined>>;
|
|
226
226
|
findMany: convex_server0.RegisteredQuery<"internal", {
|
|
227
227
|
join?: any;
|
|
228
|
-
limit?: number | undefined;
|
|
229
|
-
offset?: number | undefined;
|
|
230
|
-
sortBy?: {
|
|
231
|
-
direction: "asc" | "desc";
|
|
232
|
-
field: string;
|
|
233
|
-
} | undefined;
|
|
234
228
|
where?: {
|
|
235
229
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
236
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
237
230
|
connector?: "AND" | "OR" | undefined;
|
|
231
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
238
232
|
value: string | number | boolean | string[] | number[] | null;
|
|
239
233
|
field: string;
|
|
240
234
|
}[] | undefined;
|
|
235
|
+
limit?: number | undefined;
|
|
236
|
+
offset?: number | undefined;
|
|
237
|
+
sortBy?: {
|
|
238
|
+
direction: "asc" | "desc";
|
|
239
|
+
field: string;
|
|
240
|
+
} | undefined;
|
|
241
|
+
model: string;
|
|
241
242
|
paginationOpts: {
|
|
242
243
|
id?: number;
|
|
243
244
|
endCursor?: string | null;
|
|
@@ -246,15 +247,14 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
246
247
|
numItems: number;
|
|
247
248
|
cursor: string | null;
|
|
248
249
|
};
|
|
249
|
-
model: string;
|
|
250
250
|
}, Promise<PaginationResult<convex_server0.GenericDocument>>>;
|
|
251
251
|
findOne: convex_server0.RegisteredQuery<"internal", {
|
|
252
252
|
join?: any;
|
|
253
253
|
select?: string[] | undefined;
|
|
254
254
|
where?: {
|
|
255
255
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
256
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
257
256
|
connector?: "AND" | "OR" | undefined;
|
|
257
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
258
258
|
value: string | number | boolean | string[] | number[] | null;
|
|
259
259
|
field: string;
|
|
260
260
|
}[] | undefined;
|
|
@@ -265,8 +265,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
265
265
|
updateMany: convex_server0.RegisteredMutation<"internal", {
|
|
266
266
|
input: {
|
|
267
267
|
where?: {
|
|
268
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
269
268
|
connector?: "AND" | "OR" | undefined;
|
|
269
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
270
270
|
value: string | number | boolean | string[] | number[] | null;
|
|
271
271
|
field: string;
|
|
272
272
|
}[] | undefined;
|
|
@@ -300,8 +300,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
300
300
|
updateOne: convex_server0.RegisteredMutation<"internal", {
|
|
301
301
|
input: {
|
|
302
302
|
where?: {
|
|
303
|
-
operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
304
303
|
connector?: "AND" | "OR" | undefined;
|
|
304
|
+
operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
|
|
305
305
|
value: string | number | boolean | string[] | number[] | null;
|
|
306
306
|
field: string;
|
|
307
307
|
}[] | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kitcn",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.4",
|
|
4
4
|
"description": "kitcn - React Query integration and CLI tools for Convex",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"convex",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"common-tags": "^1.8.2",
|
|
70
70
|
"diff": "^8.0.2",
|
|
71
71
|
"dotenv": "^17.3.1",
|
|
72
|
-
"esbuild": "^0.27.
|
|
72
|
+
"esbuild": "^0.27.7",
|
|
73
73
|
"execa": "^9.6.1",
|
|
74
74
|
"jiti": "^2.6.1",
|
|
75
75
|
"jotai": "^2.18.0",
|
|
@@ -644,6 +644,12 @@ bunx kitcn aggregate backfill --prod
|
|
|
644
644
|
bunx kitcn analyze
|
|
645
645
|
```
|
|
646
646
|
|
|
647
|
+
`kitcn analyze` ranks each Convex function by the isolate it deploys into.
|
|
648
|
+
`OutMB` is that isolate's bundled size; `DepMB`/`LocMB` are the source size of
|
|
649
|
+
the dependency and own-Convex files inside it; `Files` counts the files
|
|
650
|
+
contributing bytes to it. A file that is imported but fully tree-shaken away is
|
|
651
|
+
counted in none of them. Use `--deploy` for deployment totals instead.
|
|
652
|
+
|
|
647
653
|
Concave lane:
|
|
648
654
|
|
|
649
655
|
```bash
|