@vibes.diy/api-svc 13.0.2 → 13.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ import { and, eq } from "drizzle-orm/sql/expressions";
2
+ import { exception2Result, string2stream, stream2uint8array } from "@adviser/cement";
3
+ import { isFetchErrResult, isFetchNotFoundResult } from "@vibes.diy/api-types";
4
+ import { buildCssFromCandidates, extractSourceCandidates, resetSsrTailwindCompiler } from "@vibes.diy/vibe-runtime/ssr-tailwind.js";
5
+ import { selectTopProductionRelease } from "../public/select-app.js";
6
+ const TAILWIND_ITEM_NAME = "/~~calculated~~/tailwind.css";
7
+ const TAILWIND_TRANSFORM = "tailwind-css";
8
+ const DERIVED_PREFIX = "/~~";
9
+ export const DEFAULT_TAILWIND_BACKFILL_CONCURRENCY = 2;
10
+ export function hasTailwindArtifact(fileSystem) {
11
+ if (Array.isArray(fileSystem) === false)
12
+ return false;
13
+ return fileSystem.some((i) => i?.transform?.type === TAILWIND_TRANSFORM);
14
+ }
15
+ export function rawSourceItems(fileSystem) {
16
+ if (Array.isArray(fileSystem) === false)
17
+ return [];
18
+ return fileSystem.filter((i) => typeof i?.fileName === "string" && i.fileName.startsWith(DERIVED_PREFIX) === false);
19
+ }
20
+ async function selectFileSystemAt(vctx, key) {
21
+ const t = vctx.sql.tables.apps;
22
+ const rows = await vctx.sql.db
23
+ .select({ fileSystem: t.fileSystem })
24
+ .from(t)
25
+ .where(and(eq(t.appSlug, key.appSlug), eq(t.userId, key.userId), eq(t.releaseSeq, key.releaseSeq)))
26
+ .limit(1);
27
+ return rows[0]?.fileSystem;
28
+ }
29
+ let compileGate = Promise.resolve();
30
+ async function compileIsolated(candidates) {
31
+ const run = compileGate.then(async () => {
32
+ resetSsrTailwindCompiler();
33
+ return buildCssFromCandidates(candidates);
34
+ });
35
+ compileGate = run.catch(() => undefined);
36
+ return run;
37
+ }
38
+ export async function discoverPublishedApps(vctx, opts) {
39
+ const t = vctx.sql.tables.apps;
40
+ const ownerScope = opts?.ownerHandle;
41
+ const rows = await vctx.sql.db
42
+ .select({ ownerHandle: t.ownerHandle, appSlug: t.appSlug })
43
+ .from(t)
44
+ .where(ownerScope === undefined ? eq(t.mode, "production") : and(eq(t.mode, "production"), eq(t.ownerHandle, ownerScope)))
45
+ .orderBy(t.ownerHandle, t.appSlug);
46
+ const seen = new Set();
47
+ const out = [];
48
+ for (const r of rows) {
49
+ const key = `${r.ownerHandle}/${r.appSlug}`;
50
+ if (seen.has(key))
51
+ continue;
52
+ seen.add(key);
53
+ out.push({ ownerHandle: r.ownerHandle, appSlug: r.appSlug });
54
+ if (opts?.limit !== undefined && out.length >= opts.limit)
55
+ break;
56
+ }
57
+ return out;
58
+ }
59
+ export async function processApp(vctx, app, apply) {
60
+ const base = { ownerHandle: app.ownerHandle, appSlug: app.appSlug };
61
+ const r = await exception2Result(async () => {
62
+ const live = await selectTopProductionRelease(vctx, app);
63
+ if (live === undefined)
64
+ return { ...base, outcome: "skipped", reason: "no production release" };
65
+ const fileSystem = await selectFileSystemAt(vctx, live);
66
+ if (fileSystem === undefined)
67
+ return { ...base, outcome: "skipped", releaseSeq: live.releaseSeq, reason: "release vanished" };
68
+ if (hasTailwindArtifact(fileSystem)) {
69
+ return { ...base, outcome: "skipped", releaseSeq: live.releaseSeq, reason: "already has a tailwind artifact" };
70
+ }
71
+ const sources = rawSourceItems(fileSystem);
72
+ const candidates = new Set();
73
+ for (const item of sources) {
74
+ const rFetch = await vctx.storage.fetch(item.assetURI);
75
+ if (isFetchErrResult(rFetch) || isFetchNotFoundResult(rFetch)) {
76
+ return {
77
+ ...base,
78
+ outcome: "deferred",
79
+ releaseSeq: live.releaseSeq,
80
+ reason: `source unreadable here: ${item.fileName}`,
81
+ };
82
+ }
83
+ for (const tok of extractSourceCandidates(vctx.sthis.txt.decode(await stream2uint8array(rFetch.data)))) {
84
+ candidates.add(tok);
85
+ }
86
+ }
87
+ if (candidates.size === 0) {
88
+ return { ...base, outcome: "no-candidates", releaseSeq: live.releaseSeq, candidates: 0 };
89
+ }
90
+ const css = await compileIsolated([...candidates]);
91
+ if (css === undefined) {
92
+ return {
93
+ ...base,
94
+ outcome: "failed",
95
+ releaseSeq: live.releaseSeq,
96
+ candidates: candidates.size,
97
+ reason: "tailwind compiler unavailable (missing generated assets?)",
98
+ };
99
+ }
100
+ if (apply === false) {
101
+ return { ...base, outcome: "planned", releaseSeq: live.releaseSeq, candidates: candidates.size, cssBytes: css.length };
102
+ }
103
+ const [rStore] = await vctx.storage.ensure(string2stream(css));
104
+ if (rStore.isErr()) {
105
+ return { ...base, outcome: "failed", releaseSeq: live.releaseSeq, reason: `store failed: ${rStore.Err().message}` };
106
+ }
107
+ const stored = rStore.Ok();
108
+ const item = {
109
+ fileName: TAILWIND_ITEM_NAME,
110
+ mimeType: "text/css",
111
+ assetId: stored.cid,
112
+ assetURI: stored.getURL,
113
+ transform: { type: TAILWIND_TRANSFORM },
114
+ size: css.length,
115
+ };
116
+ const t = vctx.sql.tables.apps;
117
+ await vctx.sql.db
118
+ .update(t)
119
+ .set({ fileSystem: [...fileSystem, item] })
120
+ .where(and(eq(t.appSlug, live.appSlug), eq(t.userId, live.userId), eq(t.releaseSeq, live.releaseSeq)));
121
+ const after = await vctx.sql.db
122
+ .select({ fileSystem: t.fileSystem })
123
+ .from(t)
124
+ .where(and(eq(t.appSlug, live.appSlug), eq(t.userId, live.userId), eq(t.releaseSeq, live.releaseSeq)))
125
+ .limit(1);
126
+ if (after[0] === undefined || hasTailwindArtifact(after[0].fileSystem) === false) {
127
+ return {
128
+ ...base,
129
+ outcome: "failed",
130
+ releaseSeq: live.releaseSeq,
131
+ reason: "release still has no tailwind artifact after the write",
132
+ };
133
+ }
134
+ return {
135
+ ...base,
136
+ outcome: "compiled",
137
+ releaseSeq: live.releaseSeq,
138
+ candidates: candidates.size,
139
+ cssBytes: css.length,
140
+ };
141
+ });
142
+ if (r.isErr())
143
+ return { ...base, outcome: "failed", reason: r.Err().message };
144
+ return r.Ok();
145
+ }
146
+ export async function runTailwindBackfill(vctx, opts) {
147
+ const candidates = await discoverPublishedApps(vctx, { limit: opts.limit, ownerHandle: opts.ownerHandle });
148
+ const rows = new Array(candidates.length);
149
+ const concurrency = Math.max(1, opts.concurrency ?? DEFAULT_TAILWIND_BACKFILL_CONCURRENCY);
150
+ let next = 0;
151
+ let done = 0;
152
+ async function worker() {
153
+ for (;;) {
154
+ const i = next;
155
+ next += 1;
156
+ const app = candidates[i];
157
+ if (app === undefined)
158
+ return;
159
+ const row = await processApp(vctx, app, opts.apply);
160
+ rows[i] = row;
161
+ done += 1;
162
+ opts.onRow?.(row, done, candidates.length);
163
+ }
164
+ }
165
+ await Promise.all(Array.from({ length: Math.min(concurrency, candidates.length) }, () => worker()));
166
+ const count = (o) => rows.filter((r) => r.outcome === o).length;
167
+ return {
168
+ candidates: candidates.length,
169
+ compiled: count("compiled"),
170
+ skipped: count("skipped"),
171
+ noCandidates: count("no-candidates"),
172
+ deferred: count("deferred"),
173
+ planned: count("planned"),
174
+ failed: count("failed"),
175
+ rows,
176
+ };
177
+ }
178
+ //# sourceMappingURL=backfill-release-tailwind-util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill-release-tailwind-util.js","sourceRoot":"","sources":["../../jsr/usage-report/backfill-release-tailwind-util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,109 @@
1
+ import { Pool } from "@neondatabase/serverless";
2
+ import { drizzle as drizzleNeon } from "drizzle-orm/neon-serverless";
3
+ import { Result, exception2Result } from "@adviser/cement";
4
+ import { ensureSuperThis } from "@vibes.diy/identity";
5
+ import { ensureStorage } from "@vibes.diy/api-pkg";
6
+ import { createSQLPeer, createVibesApiTables } from "@vibes.diy/api-sql";
7
+ import { DEFAULT_TAILWIND_BACKFILL_CONCURRENCY, runTailwindBackfill, } from "./backfill-release-tailwind-util.js";
8
+ import { parsePositiveIntFlag } from "./backfill-published-chips-util.js";
9
+ import { formatError, loadDevVars } from "./usage-report-util.js";
10
+ const PROGRESS_EVERY = 25;
11
+ function printUsage() {
12
+ console.log(`
13
+ Usage:
14
+ pnpm --dir vibes.diy/api/svc run admin:backfill-release-tailwind # dry run (read-only)
15
+ pnpm --dir vibes.diy/api/svc run admin:backfill-release-tailwind -- --apply # write pass
16
+ ... -- --apply --limit 50 # cap for a controlled batch
17
+ ... -- --apply --concurrency 4 # default ${DEFAULT_TAILWIND_BACKFILL_CONCURRENCY}
18
+
19
+ --limit and --concurrency take a POSITIVE INTEGER. A bad value is an error, not
20
+ a fallback — an unusable --limit must never quietly mean "sweep everything".
21
+
22
+ Environment:
23
+ NEON_DATABASE_URL read/discovery connection (dry run)
24
+ NEON_DATABASE_ADMIN_URL write connection (required for --apply)
25
+ `.trim());
26
+ }
27
+ function describe(row) {
28
+ const label = `@${row.ownerHandle}/${row.appSlug}`;
29
+ const seq = row.releaseSeq === undefined ? "" : ` seq=${row.releaseSeq}`;
30
+ const css = row.cssBytes === undefined ? "" : ` css=${row.cssBytes}B`;
31
+ const cands = row.candidates === undefined ? "" : ` cand=${row.candidates}`;
32
+ const reason = row.reason === undefined ? "" : ` (${row.reason})`;
33
+ return `${row.outcome.toUpperCase().padEnd(14)}${label}${seq}${cands}${css}${reason}`;
34
+ }
35
+ async function run() {
36
+ loadDevVars();
37
+ const args = process.argv.slice(2);
38
+ if (args.includes("--help") || args.includes("-h")) {
39
+ printUsage();
40
+ return Result.Ok(undefined);
41
+ }
42
+ const apply = args.includes("--apply");
43
+ const rLimit = parsePositiveIntFlag(args, "--limit");
44
+ if (rLimit.isErr()) {
45
+ printUsage();
46
+ return Result.Err(rLimit.Err());
47
+ }
48
+ const rConcurrency = parsePositiveIntFlag(args, "--concurrency");
49
+ if (rConcurrency.isErr()) {
50
+ printUsage();
51
+ return Result.Err(rConcurrency.Err());
52
+ }
53
+ const limit = rLimit.Ok();
54
+ const concurrency = rConcurrency.Ok() ?? DEFAULT_TAILWIND_BACKFILL_CONCURRENCY;
55
+ const connectionString = apply ? process.env["NEON_DATABASE_ADMIN_URL"] : process.env["NEON_DATABASE_URL"];
56
+ if (connectionString === undefined) {
57
+ printUsage();
58
+ return Result.Err(`${apply ? "NEON_DATABASE_ADMIN_URL" : "NEON_DATABASE_URL"} is required (set in .dev.vars or env)`);
59
+ }
60
+ const pool = new Pool({ connectionString });
61
+ const db = drizzleNeon(pool);
62
+ const tables = createVibesApiTables("pg");
63
+ const vctx = {
64
+ sthis: ensureSuperThis(),
65
+ sql: { db, tables, flavour: "pg" },
66
+ storage: ensureStorage({}, createSQLPeer({ flavour: "pg", db, assets: tables.assets })),
67
+ };
68
+ const result = await exception2Result(async () => {
69
+ const summary = await runTailwindBackfill(vctx, {
70
+ apply,
71
+ ...(limit === undefined ? {} : { limit }),
72
+ concurrency,
73
+ onRow: (row, done, total) => {
74
+ if (row.outcome === "failed" || row.outcome === "deferred")
75
+ console.log(describe(row));
76
+ if (done % PROGRESS_EVERY === 0 || done === total)
77
+ console.log(` … ${done}/${total}`);
78
+ },
79
+ });
80
+ console.log(`\ncandidates=${summary.candidates} (every published app — the artifact check happens per app)`);
81
+ if (apply === false) {
82
+ console.log(`planned=${summary.planned} skipped=${summary.skipped} no-candidates=${summary.noCandidates} deferred=${summary.deferred} failed=${summary.failed}\n` +
83
+ `skipped = live release already carries an artifact, or is not production — nothing to do.\n` +
84
+ `Dry run — nothing written. Re-run with --apply (concurrency ${concurrency}).`);
85
+ return undefined;
86
+ }
87
+ console.log(`compiled=${summary.compiled} skipped=${summary.skipped} no-candidates=${summary.noCandidates} deferred=${summary.deferred} failed=${summary.failed}\n` +
88
+ `no-candidates = the release really uses no utilities, so a deploy today would emit no artifact either.\n` +
89
+ `deferred = a source this context could not read (R2) — NOT "no utilities"; those releases still pay the per-request compile.`);
90
+ if (summary.failed > 0 || summary.deferred > 0) {
91
+ return `sweep finished with ${summary.failed} failed and ${summary.deferred} deferred app(s) — re-run to retry (covered releases are skipped)`;
92
+ }
93
+ return undefined;
94
+ });
95
+ await pool.end();
96
+ if (result.isErr())
97
+ return Result.Err(result.Err());
98
+ const partial = result.Ok();
99
+ if (partial !== undefined)
100
+ return Result.Err(partial);
101
+ return Result.Ok(undefined);
102
+ }
103
+ run().then((r) => {
104
+ if (r.isErr()) {
105
+ console.error(formatError(r.Err()));
106
+ process.exit(1);
107
+ }
108
+ });
109
+ //# sourceMappingURL=backfill-release-tailwind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill-release-tailwind.js","sourceRoot":"","sources":["../../jsr/usage-report/backfill-release-tailwind.ts"],"names":[],"mappings":"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"}