@bud.sh/app 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -31
- package/dist/client/assets/bud/design.js +1 -1
- package/dist/client/assets/canvas-Bih9EdKJ.js +1 -0
- package/dist/client/assets/difference-worker-Bzg-rizy.js +8 -0
- package/dist/client/assets/dist-CdE5wBkg.js +5 -0
- package/dist/client/assets/files-1dLuoM2f.js +1 -0
- package/dist/client/assets/i18n-CkO6VFI0.js +1 -0
- package/dist/client/assets/index-Cn2mxroU.css +2 -0
- package/dist/client/assets/{index-Dn2pfmXf.js → index-DtISWZp9.js} +2 -2
- package/dist/client/assets/pages-BJ-tNJ4J.js +1 -0
- package/dist/client/assets/{project-branches-CMGRmrqr.js → project-branches-Ce3rXrkc.js} +1 -1
- package/dist/client/assets/project-comments-CPUONfs8.js +1 -0
- package/dist/client/assets/project-thread-links-C-TGkq59.js +1 -0
- package/dist/client/assets/{project-threads-ZbKDh78d.js → project-threads-Bv7IDBgi.js} +105 -105
- package/dist/client/assets/project-work-DAE9-olg.js +1 -0
- package/dist/client/assets/{task-design-BPpc4Gd7.js → task-design-CwySIAOl.js} +3 -3
- package/dist/client/assets/tasks-KWsCLi_h.js +3 -0
- package/dist/client/assets/wasm-inline-DSUyFn1L.js +1 -0
- package/dist/client/assets/workspace-CVdcfaaB.js +2 -0
- package/dist/client/index.html +3 -3
- package/dist/hosted/assets/{canvas-BYTOp1p7.js → canvas-AII16n9i.js} +97 -6
- package/dist/hosted/assets/{comment-data-Cn5y2VxV.js → comment-data-BXfMElfx.js} +1998 -381
- package/dist/hosted/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/hosted/assets/{files-B1P2_24q.js → files-D_1yeAVO.js} +10 -5
- package/dist/hosted/assets/{pages-B0ZlVdci.js → pages-CN_SbKWA.js} +3 -3
- package/dist/hosted/assets/{project-branches-DlCWmfRo.js → project-branches-Bxp0DCwg.js} +1 -1
- package/dist/hosted/assets/{project-thread-links-BZXQ200n.js → project-thread-links-KqQoKBLE.js} +76 -4
- package/dist/{node-host/assets/screen-DapOVrga.js → hosted/assets/screen-DpAcDUKR.js} +25 -1
- package/dist/hosted/assets/tasks-D66LlwxM.js +1423 -0
- package/dist/hosted/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/hosted/hosted.js +7885 -6219
- package/dist/node/assets/Stream-CAm1eJ2n.js +16604 -0
- package/dist/{server/assets/bridge-B_Blt55E.js → node/assets/bridge-DQSBYHmw.js} +124 -290
- package/dist/node/assets/config-9_jWwNBh.js +1067 -0
- package/dist/node/assets/load-config.server-CMVtRVmO.js +261 -0
- package/dist/node/assets/module-3GgtT4Xs.js +308 -0
- package/dist/node/assets/server-DTQFuoX2.js +846 -0
- package/dist/node/assets/src-D-kG1GxB.js +2 -0
- package/dist/node/assets/{src-CerrKjID.js → src-Dwe9APUx.js} +93 -3
- package/dist/node/assets/src-DysjfbM8.js +8592 -0
- package/dist/node/bridge.js +1 -845
- package/dist/node/cli.js +206 -0
- package/dist/node/design.js +811 -8
- package/dist/node/index.js +2 -739
- package/dist/node/plugins.js +5711 -0
- package/dist/node/server.js +1 -6746
- package/dist/node/vite.js +121 -0
- package/dist/{server/assets/canvas-CkMK4hoN.js → node-host/assets/canvas-BeDoufy1.js} +97 -7
- package/dist/node-host/assets/{comment-data-yfWEdDQL.js → comment-data-DE2T9yTj.js} +1974 -355
- package/dist/node-host/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/node-host/assets/{files-anHi-apm.js → files-Dl-PTS09.js} +11 -6
- package/dist/node-host/assets/{pages-CW4aF6dK.js → pages-DL2sk6_U.js} +3 -3
- package/dist/node-host/assets/{project-branches-D7rVCxQX.js → project-branches-DGp5ELct.js} +1 -1
- package/dist/{server/assets/project-thread-links-lLS_rq7c.js → node-host/assets/project-thread-links-CgBV3Jcm.js} +76 -5
- package/dist/{hosted/assets/screen-CfdC3NbR.js → node-host/assets/screen-B55yyVfb.js} +25 -1
- package/dist/node-host/assets/tasks-DZRNkoxe.js +1425 -0
- package/dist/node-host/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/node-host/node-host.js +6127 -4438
- package/dist/server/assets/{branch-previews-ClkoJ0lM.js → branch-previews-DedrpnVR.js} +1555 -673
- package/dist/{node-host/assets/canvas-DxmcFZCh.js → server/assets/canvas-CJWQ-jjv.js} +98 -6
- package/dist/server/assets/{comment-data-NLeHG89b.js → comment-data-Rg42ToTW.js} +1660 -26
- package/dist/server/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/server/assets/{events-iHpLGr3k.js → events-BH_rAu7O.js} +155 -20
- package/dist/server/assets/{files-CRdl489E.js → files-CPJqKeMo.js} +12 -7
- package/dist/server/assets/{listener-BAYn9Q-u.js → listener-D61O6PzF.js} +708 -12
- package/dist/server/assets/{pages-DXVlJlBC.js → pages-KJY_Ba92.js} +4 -4
- package/dist/server/assets/{project-branches-CwTsf6WQ.js → project-branches-qG9ACZvo.js} +2 -2
- package/dist/{node-host/assets/project-thread-links-m-OLpsD9.js → server/assets/project-thread-links-CqK0lqCF.js} +77 -4
- package/dist/{node-host/assets/tasks-request-B0aeNocI.js → server/assets/project-work-DoIwxWMm.js} +87 -2
- package/dist/server/assets/run-BJ8r5jSh.js +572 -0
- package/dist/server/assets/{screen-B1zH_1O3.js → screen-CBrHPFug.js} +26 -2
- package/dist/server/assets/{server-DxK-UB_Z.js → server-Dkbp5stG.js} +1521 -793
- package/dist/server/assets/{services-BRrgXYlT.js → services-BTfig8A8.js} +234 -997
- package/dist/server/assets/tasks-Bgu5Lg9Y.js +1427 -0
- package/dist/server/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/server/capture.js +1 -2
- package/dist/server/migration.js +569 -12
- package/dist/server/runtime.js +7 -5
- package/dist/server/server.js +3 -3
- package/dist/types/assets/{config-DIC2cf_S.d.ts → config-CvcYmE2s.d.ts} +188 -50
- package/dist/types/assets/{contract-CAT-XFNq.d.ts → contract-B7yuuqSn.d.ts} +44 -2
- package/dist/types/assets/{items-CaVkByHk.d.ts → items-BQdaVksf.d.ts} +12 -1
- package/dist/types/assets/memory-state-BBW-FAVA.d.ts +236 -0
- package/dist/types/assets/picker-Be5Gx4WR.d.ts +9 -0
- package/dist/types/assets/{task-design-xJOhRNWh.d.ts → task-design-BDHKFHpp.d.ts} +3 -1
- package/dist/types/bridge.d.ts +1 -1
- package/dist/types/companion.d.ts +3 -3
- package/dist/types/design.d.ts +2 -2
- package/dist/types/hosted.d.ts +3 -3
- package/dist/types/index.d.ts +2 -2
- package/dist/types/node-host.d.ts +2 -2
- package/dist/types/plugins.d.ts +445 -0
- package/dist/types/screen.d.ts +2 -2
- package/dist/types/server.d.ts +2 -228
- package/dist/types/vite.d.ts +16 -0
- package/package.json +19 -3
- package/dist/client/assets/canvas-8GXJIuDK.js +0 -1
- package/dist/client/assets/difference-worker-C99ychYw.js +0 -8
- package/dist/client/assets/files-DkWt1l9H.js +0 -1
- package/dist/client/assets/i18n-hH_Ba5QO.js +0 -1
- package/dist/client/assets/index-tpHYVXma.css +0 -2
- package/dist/client/assets/pages-BVd6MQmu.js +0 -1
- package/dist/client/assets/project-comments-D1IIQwsW.js +0 -1
- package/dist/client/assets/project-thread-links-DKwe_SYb.js +0 -1
- package/dist/client/assets/project-work-D4DZqBCZ.js +0 -1
- package/dist/client/assets/tasks-Cn0VOZ9Z.js +0 -1
- package/dist/client/assets/tasks-request-BLyOzokZ.js +0 -1
- package/dist/client/assets/workspace-DGErsSg6.js +0 -2
- package/dist/hosted/assets/tasks-_yKh2Z6q.js +0 -649
- package/dist/hosted/assets/tasks-request-CFPLvLc7.js +0 -113
- package/dist/node-host/assets/tasks-BBK_CybR.js +0 -651
- package/dist/server/assets/project-work-CSZlCwH-.js +0 -88
- package/dist/server/assets/tasks-CGdz-uox.js +0 -652
- package/dist/server/assets/tasks-request-D2NBjCTl.js +0 -115
- package/dist/types/assets/picker-D1Bw3ndx.d.ts +0 -14
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { n as normalizeOrigin, r as resolveBudConfig } from "./config-9_jWwNBh.js";
|
|
2
|
+
import { A as await_, At as runPromise, Ct as provideContext, Dt as runCallbackWith, Et as runCallback, Ft as runSyncExit, Gt as tryPromise, Ht as sync, It as runSyncExitWith, Jt as withFiber, K as catchIf, Kt as try_, Ln as scopeRemoveFinalizerUnsafe, Lt as runSyncWith, Mn as void_$1, Mt as runPromiseExitWith, Nt as runPromiseWith, Ot as runFork, Pt as runSync, Sn as makeUnsafe, Ur as TaggedError, Ut as tap, X as die, Y as context, _n as provideMerge, _t as mapError, at as flatten, bn as close, dn as buildWithMemoMap, fn as effect, ft as gen, hn as mergeAll, j as runIn, jt as runPromiseExit, kt as runForkWith, mn as makeMemoMapUnsafe, pr as Service, qt as void_, rt as flatMap, vn as succeed, xn as forkUnsafe } from "./Stream-CAm1eJ2n.js";
|
|
3
|
+
import { C as Path, n as readText, t as nodeLayer, w as FileSystem } from "./src-DysjfbM8.js";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
//#region ../project/src/server/errors.ts
|
|
7
|
+
/** Expected project startup/configuration failure; nested causes remain server-only. */
|
|
8
|
+
var ProjectError = class extends TaggedError("ProjectError") {};
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region ../project/src/server/config.ts
|
|
11
|
+
/** Trusted executable configuration; tests replace evaluation independently of filesystem I/O. */
|
|
12
|
+
var ConfigModuleLoader = class extends Service()("@bud.sh/project/ConfigModuleLoader") {};
|
|
13
|
+
var configModuleLoaderLayer = succeed(ConfigModuleLoader, { load: (filename) => tryPromise({
|
|
14
|
+
try: async () => {
|
|
15
|
+
let url = pathToFileURL(filename);
|
|
16
|
+
url.searchParams.set("bud", randomUUID());
|
|
17
|
+
return (await import(
|
|
18
|
+
/* @vite-ignore */
|
|
19
|
+
url.href
|
|
20
|
+
)).default;
|
|
21
|
+
},
|
|
22
|
+
catch: (cause) => new ProjectError({
|
|
23
|
+
reason: "evaluate",
|
|
24
|
+
filename,
|
|
25
|
+
message: `Could not evaluate ${filename}: ${cause instanceof Error ? cause.message : "the config module failed"}`,
|
|
26
|
+
cause
|
|
27
|
+
})
|
|
28
|
+
}) });
|
|
29
|
+
/** Finds, evaluates and validates a project's bud.config.ts. */
|
|
30
|
+
var ProjectConfig = class extends Service()("@bud.sh/project/ProjectConfig") {};
|
|
31
|
+
function projectError(reason, message, filename) {
|
|
32
|
+
return (cause) => new ProjectError({
|
|
33
|
+
reason,
|
|
34
|
+
message,
|
|
35
|
+
filename,
|
|
36
|
+
cause
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Discovers exactly one config and validates it before any companion listener is opened. */
|
|
40
|
+
var projectConfigLayer = effect(ProjectConfig, gen(function* () {
|
|
41
|
+
let fs = yield* FileSystem;
|
|
42
|
+
let path = yield* Path;
|
|
43
|
+
let loader = yield* ConfigModuleLoader;
|
|
44
|
+
let boundedRead = yield* context();
|
|
45
|
+
return { load: (directory) => gen(function* () {
|
|
46
|
+
if (typeof directory !== "string" || !directory.trim() || directory.includes("\0")) return yield* new ProjectError({
|
|
47
|
+
reason: "root",
|
|
48
|
+
message: "A valid project directory is required."
|
|
49
|
+
});
|
|
50
|
+
let root = yield* fs.realPath(path.resolve(directory)).pipe(mapError(projectError("root", `Cannot open project directory ${directory}.`)));
|
|
51
|
+
if ((yield* fs.stat(root).pipe(mapError(projectError("root", `Cannot inspect project directory ${root}.`)))).type !== "Directory") return yield* new ProjectError({
|
|
52
|
+
reason: "root",
|
|
53
|
+
message: `${root} is not a project directory.`
|
|
54
|
+
});
|
|
55
|
+
let files = [];
|
|
56
|
+
for (let name of ["bud.config.ts", "bud.config.js"]) {
|
|
57
|
+
let filename = path.join(root, name);
|
|
58
|
+
let info = yield* fs.stat(filename).pipe(catchIf((error) => error.reason._tag === "NotFound", () => void_), mapError(projectError("read", `Cannot inspect ${filename}.`, filename)));
|
|
59
|
+
if (!info) continue;
|
|
60
|
+
if (info.type !== "File") return yield* new ProjectError({
|
|
61
|
+
reason: "invalid",
|
|
62
|
+
filename,
|
|
63
|
+
message: `${filename} must be a regular config file.`
|
|
64
|
+
});
|
|
65
|
+
files.push(filename);
|
|
66
|
+
}
|
|
67
|
+
if (files.length !== 1) return yield* new ProjectError({
|
|
68
|
+
reason: files.length === 0 ? "missing" : "ambiguous",
|
|
69
|
+
message: files.length === 0 ? `Add bud.config.ts or bud.config.js in ${root}.` : "Keep exactly one bud.config.ts or bud.config.js."
|
|
70
|
+
});
|
|
71
|
+
let filename = files[0];
|
|
72
|
+
yield* readText(filename).pipe(provideContext(boundedRead), mapError((cause) => new ProjectError({
|
|
73
|
+
reason: "read",
|
|
74
|
+
filename,
|
|
75
|
+
message: `Cannot read ${filename}: ${cause.message}`,
|
|
76
|
+
cause
|
|
77
|
+
})));
|
|
78
|
+
let value = yield* loader.load(filename);
|
|
79
|
+
return {
|
|
80
|
+
root,
|
|
81
|
+
filename,
|
|
82
|
+
config: yield* try_({
|
|
83
|
+
try: () => resolveBudConfig(value),
|
|
84
|
+
catch: (cause) => new ProjectError({
|
|
85
|
+
reason: "invalid",
|
|
86
|
+
filename,
|
|
87
|
+
message: cause instanceof Error ? cause.message : "Invalid Bud configuration.",
|
|
88
|
+
cause
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
};
|
|
92
|
+
}) };
|
|
93
|
+
}));
|
|
94
|
+
Service()("@bud.sh/project/Project");
|
|
95
|
+
var invalidTarget = "The target must be an HTTP(S) origin without a path or credentials.";
|
|
96
|
+
/**
|
|
97
|
+
* Resolves the actual bound target port, retaining an explicit target override.
|
|
98
|
+
* @param config - Validated project configuration.
|
|
99
|
+
* @param address - The live target listener address.
|
|
100
|
+
* @param options - Target transport and host settings.
|
|
101
|
+
* @returns A validated preview origin or a typed startup failure.
|
|
102
|
+
*/
|
|
103
|
+
function resolveTargetOrigin(config, address, options = {}) {
|
|
104
|
+
return try_({
|
|
105
|
+
try: () => {
|
|
106
|
+
if (config.targetOrigin) return normalizeOrigin(config.targetOrigin, invalidTarget);
|
|
107
|
+
if (!address || typeof address === "string" || !Number.isInteger(address.port) || address.port < 1 || address.port > 65535) throw new Error("Bud needs a listening Vite HTTP server to discover its port.");
|
|
108
|
+
let wildcard = (value) => [
|
|
109
|
+
"0.0.0.0",
|
|
110
|
+
"::",
|
|
111
|
+
""
|
|
112
|
+
].includes(value);
|
|
113
|
+
let host = typeof options.host === "string" && !wildcard(options.host) ? options.host : address.address && !wildcard(address.address) ? address.address : "127.0.0.1";
|
|
114
|
+
if (host.includes(":") && !host.startsWith("[")) host = `[${host}]`;
|
|
115
|
+
return normalizeOrigin(`${options.https ? "https" : "http"}://${host}:${address.port}`, invalidTarget);
|
|
116
|
+
},
|
|
117
|
+
catch: (cause) => new ProjectError({
|
|
118
|
+
reason: "target",
|
|
119
|
+
message: cause instanceof Error ? cause.message : "Cannot resolve the preview origin.",
|
|
120
|
+
cause
|
|
121
|
+
})
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region ../../node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/ManagedRuntime.js
|
|
126
|
+
var TypeId = "~effect/ManagedRuntime";
|
|
127
|
+
/**
|
|
128
|
+
* Creates a `ManagedRuntime` from a layer.
|
|
129
|
+
*
|
|
130
|
+
* **When to use**
|
|
131
|
+
*
|
|
132
|
+
* Use to create a reusable runtime from a `Layer` for application entry points
|
|
133
|
+
* or integration code that runs many effects without rebuilding services.
|
|
134
|
+
*
|
|
135
|
+
* **Details**
|
|
136
|
+
*
|
|
137
|
+
* The layer is built lazily on first use and its context is cached for
|
|
138
|
+
* subsequent runs. Resources acquired by the layer are owned by the runtime and
|
|
139
|
+
* are released when `dispose` or `disposeEffect` is run. `options.memoMap` can
|
|
140
|
+
* be used to share layer memoization with other layer builds.
|
|
141
|
+
*
|
|
142
|
+
* **Gotchas**
|
|
143
|
+
*
|
|
144
|
+
* Dispose the runtime when it is no longer needed. A runtime cannot be reused
|
|
145
|
+
* after disposal.
|
|
146
|
+
*
|
|
147
|
+
* **Example** (Creating a managed runtime)
|
|
148
|
+
*
|
|
149
|
+
* ```ts import.meta.vitest
|
|
150
|
+
* import { Context, Effect, Layer, ManagedRuntime } from "effect"
|
|
151
|
+
*
|
|
152
|
+
* const notifications: Array<string> = []
|
|
153
|
+
*
|
|
154
|
+
* class Notifications extends Context.Service<Notifications, {
|
|
155
|
+
* readonly notify: (message: string) => Effect.Effect<void>
|
|
156
|
+
* }>()("Notifications") {
|
|
157
|
+
* static readonly layer = Layer.succeed(this)({
|
|
158
|
+
* notify: Effect.fn("Notifications.notify")((message) =>
|
|
159
|
+
* Effect.sync(() => notifications.push(message))
|
|
160
|
+
* )
|
|
161
|
+
* })
|
|
162
|
+
* }
|
|
163
|
+
*
|
|
164
|
+
* const runtime = ManagedRuntime.make(Notifications.layer)
|
|
165
|
+
*
|
|
166
|
+
* const program = Effect.flatMap(
|
|
167
|
+
* Notifications,
|
|
168
|
+
* (_) => _.notify("Hello, world!")
|
|
169
|
+
* ).pipe(Effect.ensuring(runtime.disposeEffect))
|
|
170
|
+
*
|
|
171
|
+
* await runtime.runPromise(program)
|
|
172
|
+
* notifications // => ["Hello, world!"]
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @see {@link ManagedRuntime} for the returned runtime interface
|
|
176
|
+
* @see {@link Layer.MemoMap} for shared layer memoization
|
|
177
|
+
* @see {@link Layer.build} for lower-level scoped layer construction
|
|
178
|
+
*
|
|
179
|
+
* @stability stable
|
|
180
|
+
* @category constructors
|
|
181
|
+
* @since 2.0.0
|
|
182
|
+
*/
|
|
183
|
+
var make = (layer, options) => {
|
|
184
|
+
const memoMap = options?.memoMap ?? makeMemoMapUnsafe();
|
|
185
|
+
const scope = makeUnsafe("sequential");
|
|
186
|
+
const layerScope = forkUnsafe(scope, "sequential");
|
|
187
|
+
const fiberScope = forkUnsafe(scope, "parallel");
|
|
188
|
+
const defaultRunOptions = { onFiberStart: runIn(fiberScope) };
|
|
189
|
+
const mergeRunOptions = (options) => options ? {
|
|
190
|
+
...options,
|
|
191
|
+
onFiberStart: options.onFiberStart ? (fiber) => {
|
|
192
|
+
defaultRunOptions.onFiberStart(fiber);
|
|
193
|
+
options.onFiberStart(fiber);
|
|
194
|
+
} : defaultRunOptions.onFiberStart
|
|
195
|
+
} : defaultRunOptions;
|
|
196
|
+
let buildFiber;
|
|
197
|
+
const contextEffect = withFiber((fiber) => {
|
|
198
|
+
if (!buildFiber) buildFiber = runFork(tap(buildWithMemoMap(layer, memoMap, layerScope), (context) => sync(() => {
|
|
199
|
+
self.cachedContext = context;
|
|
200
|
+
})), {
|
|
201
|
+
...defaultRunOptions,
|
|
202
|
+
scheduler: fiber.cache.scheduler
|
|
203
|
+
});
|
|
204
|
+
return flatten(await_(buildFiber));
|
|
205
|
+
});
|
|
206
|
+
const self = {
|
|
207
|
+
[TypeId]: TypeId,
|
|
208
|
+
memoMap,
|
|
209
|
+
scope,
|
|
210
|
+
contextEffect,
|
|
211
|
+
cachedContext: void 0,
|
|
212
|
+
context() {
|
|
213
|
+
return self.cachedContext === void 0 ? runPromise(self.contextEffect) : Promise.resolve(self.cachedContext);
|
|
214
|
+
},
|
|
215
|
+
dispose() {
|
|
216
|
+
return runPromise(self.disposeEffect);
|
|
217
|
+
},
|
|
218
|
+
[Symbol.asyncDispose]() {
|
|
219
|
+
return self.dispose();
|
|
220
|
+
},
|
|
221
|
+
disposeEffect: withFiber((fiber) => {
|
|
222
|
+
for (let current = fiber; current; current = current._parent) scopeRemoveFinalizerUnsafe(fiberScope, current);
|
|
223
|
+
self.contextEffect = die("ManagedRuntime disposed");
|
|
224
|
+
self.cachedContext = void 0;
|
|
225
|
+
return close(self.scope, void_$1);
|
|
226
|
+
}),
|
|
227
|
+
runFork(effect, options) {
|
|
228
|
+
return self.cachedContext === void 0 ? runFork(provide(self, effect), mergeRunOptions(options)) : runForkWith(self.cachedContext)(effect, mergeRunOptions(options));
|
|
229
|
+
},
|
|
230
|
+
runCallback(effect, options) {
|
|
231
|
+
return self.cachedContext === void 0 ? runCallback(provide(self, effect), mergeRunOptions(options)) : runCallbackWith(self.cachedContext)(effect, mergeRunOptions(options));
|
|
232
|
+
},
|
|
233
|
+
runSyncExit(effect) {
|
|
234
|
+
return self.cachedContext === void 0 ? runSyncExit(provide(self, effect)) : runSyncExitWith(self.cachedContext)(effect);
|
|
235
|
+
},
|
|
236
|
+
runSync(effect) {
|
|
237
|
+
return self.cachedContext === void 0 ? runSync(provide(self, effect)) : runSyncWith(self.cachedContext)(effect);
|
|
238
|
+
},
|
|
239
|
+
runPromiseExit(effect, options) {
|
|
240
|
+
return self.cachedContext === void 0 ? runPromiseExit(provide(self, effect), mergeRunOptions(options)) : runPromiseExitWith(self.cachedContext)(effect, mergeRunOptions(options));
|
|
241
|
+
},
|
|
242
|
+
runPromise(effect, options) {
|
|
243
|
+
return self.cachedContext === void 0 ? runPromise(provide(self, effect), mergeRunOptions(options)) : runPromiseWith(self.cachedContext)(effect, mergeRunOptions(options));
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
return self;
|
|
247
|
+
};
|
|
248
|
+
function provide(managed, effect) {
|
|
249
|
+
return flatMap(managed.contextEffect, (context) => provideContext(effect, context));
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/host/load-config.server.ts
|
|
253
|
+
/**
|
|
254
|
+
* A Node runtime that loads and resolves a project's bud.config.ts; dispose it when done.
|
|
255
|
+
* @returns The managed runtime.
|
|
256
|
+
*/
|
|
257
|
+
function createConfigRuntime() {
|
|
258
|
+
return make(provideMerge(projectConfigLayer, mergeAll(nodeLayer(), configModuleLoaderLayer)));
|
|
259
|
+
}
|
|
260
|
+
//#endregion
|
|
261
|
+
export { ProjectError as i, resolveTargetOrigin as n, ProjectConfig as r, createConfigRuntime as t };
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
//#region ../picker-react-grab/src/lib/adapter.ts
|
|
2
|
+
/**
|
|
3
|
+
* The page side of `bud:react` and `bud:react-grab`: an element's component and source come from
|
|
4
|
+
* React's development build, its block is the component's outermost element, and with React Grab
|
|
5
|
+
* its own selection picks. It runs in the project's pages as module or script text, so it must not
|
|
6
|
+
* reference anything outside its own body. The line comes from React's own stack, mapped through
|
|
7
|
+
* the module's source map, so it is exact whichever React Grab a project runs; React Grab's own
|
|
8
|
+
* answer fills in what that can't find. Production builds keep no source, so only the DOM picker's
|
|
9
|
+
* own description remains.
|
|
10
|
+
* @param grab - The project's `react-grab` module, or null to read React alone. Importing it
|
|
11
|
+
* starts React Grab if it isn't yet.
|
|
12
|
+
* @param helpers - Resolves file names and source map positions.
|
|
13
|
+
* @returns The picker adapter.
|
|
14
|
+
*/
|
|
15
|
+
function reactGrabAdapter(grab, helpers) {
|
|
16
|
+
let { sourceFile, projectFrames, sourceMapLookup } = helpers;
|
|
17
|
+
let plugin = "bud:picker";
|
|
18
|
+
let maps = /* @__PURE__ */ new Map();
|
|
19
|
+
let host = 5;
|
|
20
|
+
function fiberOf(element) {
|
|
21
|
+
let key = Object.keys(element).find((name) => name.startsWith("__reactFiber$"));
|
|
22
|
+
return key ? element[key] ?? null : null;
|
|
23
|
+
}
|
|
24
|
+
function outermost(component) {
|
|
25
|
+
let node = component.child;
|
|
26
|
+
while (node && node.tag !== host) node = node.child;
|
|
27
|
+
return node?.stateNode instanceof Element ? node.stateNode : null;
|
|
28
|
+
}
|
|
29
|
+
function sourceMap(url) {
|
|
30
|
+
let cached = maps.get(url);
|
|
31
|
+
if (cached) return cached;
|
|
32
|
+
cached = fetch(url).then((response) => response.ok ? response.text() : "").then(async (text) => {
|
|
33
|
+
let reference = /\/\/[#@] sourceMappingURL=(\S+)\s*$/.exec(text)?.[1];
|
|
34
|
+
let address = new URL(reference ?? `${url.replace(/[?#].*$/, "")}.map`, url);
|
|
35
|
+
if (address.protocol !== "data:" && address.origin !== location.origin) return null;
|
|
36
|
+
let response = await fetch(address);
|
|
37
|
+
let map = response.ok ? await response.json() : null;
|
|
38
|
+
let lookup = map && typeof map === "object" ? sourceMapLookup(map) : null;
|
|
39
|
+
return lookup ? {
|
|
40
|
+
lookup,
|
|
41
|
+
base: address.protocol === "data:" ? url : address.href
|
|
42
|
+
} : null;
|
|
43
|
+
}).catch(() => null);
|
|
44
|
+
maps.set(url, cached);
|
|
45
|
+
if (maps.size > 50) maps.delete(maps.keys().next().value);
|
|
46
|
+
return cached;
|
|
47
|
+
}
|
|
48
|
+
function servedPath(source, base, stack) {
|
|
49
|
+
if (source.startsWith("/") && !source.startsWith("//")) return sourceFile(source, stack, location.origin);
|
|
50
|
+
let url = new URL(source, base);
|
|
51
|
+
return url.origin === location.origin && !url.pathname.startsWith("/@") && !url.pathname.includes("/node_modules/") ? url.pathname : null;
|
|
52
|
+
}
|
|
53
|
+
async function written(stack) {
|
|
54
|
+
let frames = projectFrames(stack, location.origin);
|
|
55
|
+
for (let frame of frames) {
|
|
56
|
+
let map = await sourceMap(frame.url);
|
|
57
|
+
let position = map ? map.lookup(frame.line, frame.column) : {
|
|
58
|
+
source: frame.url,
|
|
59
|
+
line: frame.line,
|
|
60
|
+
column: frame.column
|
|
61
|
+
};
|
|
62
|
+
if (!position) continue;
|
|
63
|
+
let file = servedPath(position.source, map?.base ?? frame.url, stack);
|
|
64
|
+
if (file) return {
|
|
65
|
+
name: frame.name,
|
|
66
|
+
file,
|
|
67
|
+
line: position.line,
|
|
68
|
+
column: position.column
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return frames[0] ? {
|
|
72
|
+
name: frames[0].name,
|
|
73
|
+
file: null,
|
|
74
|
+
line: null,
|
|
75
|
+
column: null
|
|
76
|
+
} : null;
|
|
77
|
+
}
|
|
78
|
+
function ownerName(element) {
|
|
79
|
+
let type = fiberOf(element)?._debugOwner?.type;
|
|
80
|
+
let name = type && typeof type === "object" ? type.displayName ?? type.name : null;
|
|
81
|
+
return typeof name === "string" && name ? name : null;
|
|
82
|
+
}
|
|
83
|
+
let adapter = {
|
|
84
|
+
async describe(element) {
|
|
85
|
+
let api = grab?.getGlobalApi() ?? null;
|
|
86
|
+
let stack = fiberOf(element)?._debugStack?.stack ?? "";
|
|
87
|
+
let mapped = stack ? await written(stack).catch(() => null) : null;
|
|
88
|
+
let found = !mapped?.file && api ? await api.getSource(element).catch(() => null) : null;
|
|
89
|
+
let component = mapped?.name ?? found?.componentName ?? api?.getDisplayName(element) ?? ownerName(element);
|
|
90
|
+
if (!mapped?.file && !found && !component) return null;
|
|
91
|
+
if (mapped?.file) return { source: {
|
|
92
|
+
component: component || null,
|
|
93
|
+
file: mapped.file,
|
|
94
|
+
line: mapped.line,
|
|
95
|
+
column: mapped.column
|
|
96
|
+
} };
|
|
97
|
+
let file = found?.filePath ? sourceFile(found.filePath, stack, location.origin) : null;
|
|
98
|
+
let line = found?.lineNumber && found.lineNumber > 0 ? found.lineNumber : null;
|
|
99
|
+
let column = found?.columnNumber != null && found.columnNumber >= 0 ? found.columnNumber + 1 : null;
|
|
100
|
+
return { source: {
|
|
101
|
+
component: component || null,
|
|
102
|
+
file,
|
|
103
|
+
line,
|
|
104
|
+
column
|
|
105
|
+
} };
|
|
106
|
+
},
|
|
107
|
+
block(element) {
|
|
108
|
+
for (let owner = fiberOf(element)?._debugOwner; owner; owner = owner._debugOwner) {
|
|
109
|
+
let outer = outermost(owner);
|
|
110
|
+
if (outer && outer !== document.body && outer.contains(element)) return outer;
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
if (!grab) return adapter;
|
|
116
|
+
return {
|
|
117
|
+
...adapter,
|
|
118
|
+
pick(signal) {
|
|
119
|
+
let api = grab.getGlobalApi();
|
|
120
|
+
if (!api || signal.aborted) return Promise.resolve(null);
|
|
121
|
+
return new Promise((resolve) => {
|
|
122
|
+
let settled = false;
|
|
123
|
+
let tidy = () => {
|
|
124
|
+
api.unregisterPlugin(plugin);
|
|
125
|
+
if (api.isActive()) api.deactivate();
|
|
126
|
+
};
|
|
127
|
+
let finish = (element, during) => {
|
|
128
|
+
if (settled) return;
|
|
129
|
+
settled = true;
|
|
130
|
+
signal.removeEventListener("abort", cancel);
|
|
131
|
+
resolve(element);
|
|
132
|
+
if (during) setTimeout(tidy, 1e3);
|
|
133
|
+
else tidy();
|
|
134
|
+
};
|
|
135
|
+
let cancel = () => finish(null, false);
|
|
136
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
137
|
+
api.unregisterPlugin(plugin);
|
|
138
|
+
api.registerPlugin({
|
|
139
|
+
name: plugin,
|
|
140
|
+
theme: { grabbedBoxes: { enabled: false } },
|
|
141
|
+
hooks: {
|
|
142
|
+
onElementSelect(element) {
|
|
143
|
+
finish(element, true);
|
|
144
|
+
return true;
|
|
145
|
+
},
|
|
146
|
+
onDeactivate: () => finish(null, true)
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
api.activate();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region ../picker-react-grab/src/lib/source-map.ts
|
|
156
|
+
/**
|
|
157
|
+
* The frames of React's stack for an element that may have run in the project's own code, in
|
|
158
|
+
* order: the first one whose source is the project's is the component that rendered it.
|
|
159
|
+
* Dependencies the dev server serves apart, Vite's own modules and other origins are left out; a
|
|
160
|
+
* build bundles dependencies with the project, so their frames stay for their source maps to
|
|
161
|
+
* tell apart. It runs in the project's pages as module text, so it must not reference anything
|
|
162
|
+
* outside its own body.
|
|
163
|
+
* @param stack - React's stack for the element, as `Error.stack` text.
|
|
164
|
+
* @param origin - The page's origin.
|
|
165
|
+
* @returns The frames, possibly none.
|
|
166
|
+
*/
|
|
167
|
+
function projectFrames(stack, origin) {
|
|
168
|
+
let frames = [];
|
|
169
|
+
for (let text of stack.split("\n")) {
|
|
170
|
+
let match = /^\s*at (?:(.+?) \()?(https?:\/\/[^\s()]+?):(\d+):(\d+)\)?\s*$/.exec(text);
|
|
171
|
+
if (!match) continue;
|
|
172
|
+
let url = new URL(match[2]);
|
|
173
|
+
if (url.origin !== origin || url.pathname.startsWith("/@") || url.pathname.includes("/node_modules/")) continue;
|
|
174
|
+
let name = match[1]?.replace(/^Object\./, "") ?? null;
|
|
175
|
+
frames.push({
|
|
176
|
+
name,
|
|
177
|
+
url: url.href,
|
|
178
|
+
line: Number(match[3]),
|
|
179
|
+
column: Number(match[4])
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return frames;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Decodes a module's source map once, for looking up many positions in it. It runs in the
|
|
186
|
+
* project's pages as module text, so it must not reference anything outside its own body.
|
|
187
|
+
* @param map - The source map, as parsed JSON.
|
|
188
|
+
* @returns Maps a generated line and column, counted from one, to the original position; null
|
|
189
|
+
* for a map that can't be read.
|
|
190
|
+
*/
|
|
191
|
+
function sourceMapLookup(map) {
|
|
192
|
+
if (typeof map.mappings !== "string" || !Array.isArray(map.sources)) return null;
|
|
193
|
+
let sources = map.sources;
|
|
194
|
+
let root = typeof map.sourceRoot === "string" && map.sourceRoot ? map.sourceRoot : "";
|
|
195
|
+
let digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
196
|
+
let lines = [];
|
|
197
|
+
let source = 0;
|
|
198
|
+
let sourceLine = 0;
|
|
199
|
+
let sourceColumn = 0;
|
|
200
|
+
for (let text of map.mappings.split(";")) {
|
|
201
|
+
let generated = 0;
|
|
202
|
+
let segments = [];
|
|
203
|
+
for (let segment of text.split(",")) {
|
|
204
|
+
if (!segment) continue;
|
|
205
|
+
let values = [];
|
|
206
|
+
let value = 0;
|
|
207
|
+
let shift = 0;
|
|
208
|
+
for (let character of segment) {
|
|
209
|
+
let digit = digits.indexOf(character);
|
|
210
|
+
if (digit < 0) return null;
|
|
211
|
+
value += (digit & 31) << shift;
|
|
212
|
+
if (digit & 32) shift += 5;
|
|
213
|
+
else {
|
|
214
|
+
values.push(value & 1 ? -(value >>> 1) : value >>> 1);
|
|
215
|
+
value = 0;
|
|
216
|
+
shift = 0;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
generated += values[0] ?? 0;
|
|
220
|
+
if (values.length < 4) continue;
|
|
221
|
+
source += values[1];
|
|
222
|
+
sourceLine += values[2];
|
|
223
|
+
sourceColumn += values[3];
|
|
224
|
+
segments.push([
|
|
225
|
+
generated,
|
|
226
|
+
source,
|
|
227
|
+
sourceLine,
|
|
228
|
+
sourceColumn
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
lines.push(segments);
|
|
232
|
+
}
|
|
233
|
+
return (line, column) => {
|
|
234
|
+
let found = null;
|
|
235
|
+
for (let segment of lines[line - 1] ?? []) if (segment[0] <= column - 1) found = segment;
|
|
236
|
+
let name = found ? sources[found[1]] : null;
|
|
237
|
+
if (!found || typeof name !== "string") return null;
|
|
238
|
+
return {
|
|
239
|
+
source: root ? `${root.replace(/\/$/, "")}/${name}` : name,
|
|
240
|
+
line: found[2] + 1,
|
|
241
|
+
column: found[3] + 1
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
//#endregion
|
|
246
|
+
//#region ../picker-react-grab/src/lib/source.ts
|
|
247
|
+
/**
|
|
248
|
+
* The project path of a file React Grab names. React Grab maps React's stack through the dev
|
|
249
|
+
* server's source maps, whose sources are relative to the module that names them (Vite writes
|
|
250
|
+
* `card.tsx` for `/src/components/card.tsx`). The module's address is still in React's own stack,
|
|
251
|
+
* so the file resolves against the first frame from the page's origin that shares its name. It runs
|
|
252
|
+
* in the project's pages as module text, so it must not reference anything outside its own body.
|
|
253
|
+
* @param file - The file React Grab reported: a name, a relative or absolute path, or a URL.
|
|
254
|
+
* @param stack - React's stack for the element, as `Error.stack` text.
|
|
255
|
+
* @param origin - The page's origin; frames from elsewhere are never the project's.
|
|
256
|
+
* @returns A path as the dev server serves it, such as `/src/components/card.tsx`, or null.
|
|
257
|
+
*/
|
|
258
|
+
function sourceFile(file, stack, origin) {
|
|
259
|
+
let served = (url) => url.origin === origin && !url.pathname.startsWith("/@") && !url.pathname.includes("/node_modules/") && !/[\\\u0000-\u001f\u007f]/.test(url.pathname);
|
|
260
|
+
if (/^https?:\/\//.test(file)) {
|
|
261
|
+
let url = new URL(file);
|
|
262
|
+
return served(url) ? url.pathname : null;
|
|
263
|
+
}
|
|
264
|
+
let name = file.split("/").pop();
|
|
265
|
+
for (let line of stack.split("\n")) {
|
|
266
|
+
let match = /(https?:\/\/[^\s()]+?)(?::\d+){1,2}\)?\s*$/.exec(line);
|
|
267
|
+
if (!match) continue;
|
|
268
|
+
let frame = new URL(match[1]);
|
|
269
|
+
if (!served(frame) || frame.pathname.split("/").pop() !== name) continue;
|
|
270
|
+
if (file.startsWith("/")) return file.endsWith(frame.pathname) ? frame.pathname : null;
|
|
271
|
+
let resolved = new URL(file, frame);
|
|
272
|
+
return served(resolved) ? resolved.pathname : null;
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region ../picker-react-grab/src/lib/module.ts
|
|
278
|
+
/** The React Grab picker's name in `bud.config`. */
|
|
279
|
+
var REACT_GRAB_PICKER = "bud:react-grab";
|
|
280
|
+
/** The picker that reads React alone, without React Grab, in `bud.config`. */
|
|
281
|
+
var REACT_PICKER = "bud:react";
|
|
282
|
+
function helpers() {
|
|
283
|
+
return [
|
|
284
|
+
"{",
|
|
285
|
+
` sourceFile: ${sourceFile.toString()},`,
|
|
286
|
+
` projectFrames: ${projectFrames.toString()},`,
|
|
287
|
+
` sourceMapLookup: ${sourceMapLookup.toString()},`,
|
|
288
|
+
"}"
|
|
289
|
+
].join("\n");
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* The adapter's page module text. It imports `react-grab` from the project, so React Grab must be
|
|
293
|
+
* installed there; the dev server serves the same instance the project's pages use.
|
|
294
|
+
* @returns ES module text whose default export is the picker adapter.
|
|
295
|
+
*/
|
|
296
|
+
function reactGrabAdapterModule() {
|
|
297
|
+
return ["import * as grab from 'react-grab'", `export default (${reactGrabAdapter.toString()})(grab, ${helpers()})`].join("\n");
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* An expression that builds the React adapter without React Grab, for module or script text.
|
|
301
|
+
* It needs nothing from the project, so pages without a dev server can run it too.
|
|
302
|
+
* @returns JavaScript expression text evaluating to the picker adapter.
|
|
303
|
+
*/
|
|
304
|
+
function reactAdapterExpression() {
|
|
305
|
+
return `(${reactGrabAdapter.toString()})(null, ${helpers()})`;
|
|
306
|
+
}
|
|
307
|
+
//#endregion
|
|
308
|
+
export { reactGrabAdapterModule as i, REACT_PICKER as n, reactAdapterExpression as r, REACT_GRAB_PICKER as t };
|