@gaganref/confect-cli 0.0.0-stage → 10.3.1-fork.10
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 +1824 -0
- package/LICENSE +7 -0
- package/README.md +16 -2
- package/bin/confect.mjs +26 -0
- package/dist/Ansi.mjs +18 -0
- package/dist/Ansi.mjs.map +1 -0
- package/dist/BuildError.mjs +30 -0
- package/dist/BuildError.mjs.map +1 -0
- package/dist/Bundler.mjs +426 -0
- package/dist/Bundler.mjs.map +1 -0
- package/dist/CodeBlockWriter.mjs +55 -0
- package/dist/CodeBlockWriter.mjs.map +1 -0
- package/dist/CodegenError.mjs +194 -0
- package/dist/CodegenError.mjs.map +1 -0
- package/dist/ConfectDirectory.mjs +35 -0
- package/dist/ConfectDirectory.mjs.map +1 -0
- package/dist/ConvexConfig.mjs +198 -0
- package/dist/ConvexConfig.mjs.map +1 -0
- package/dist/ConvexDirectory.mjs +54 -0
- package/dist/ConvexDirectory.mjs.map +1 -0
- package/dist/Declaration.mjs +258 -0
- package/dist/Declaration.mjs.map +1 -0
- package/dist/DirectoryOptions.mjs +42 -0
- package/dist/DirectoryOptions.mjs.map +1 -0
- package/dist/DocName.mjs +25 -0
- package/dist/DocName.mjs.map +1 -0
- package/dist/EntryPoint.mjs +111 -0
- package/dist/EntryPoint.mjs.map +1 -0
- package/dist/Evaluation.mjs +117 -0
- package/dist/Evaluation.mjs.map +1 -0
- package/dist/EvaluationWorker.mjs +46 -0
- package/dist/EvaluationWorker.mjs.map +1 -0
- package/dist/FunctionModule.mjs +137 -0
- package/dist/FunctionModule.mjs.map +1 -0
- package/dist/FunctionPath.mjs +18 -0
- package/dist/FunctionPath.mjs.map +1 -0
- package/dist/FunctionPaths.mjs +45 -0
- package/dist/FunctionPaths.mjs.map +1 -0
- package/dist/GenerationSnapshot.mjs +183 -0
- package/dist/GenerationSnapshot.mjs.map +1 -0
- package/dist/GroupPath.mjs +51 -0
- package/dist/GroupPath.mjs.map +1 -0
- package/dist/GroupPaths.mjs +8 -0
- package/dist/GroupPaths.mjs.map +1 -0
- package/dist/ImplModulePath.mjs +8 -0
- package/dist/ImplModulePath.mjs.map +1 -0
- package/dist/LeafModule.mjs +285 -0
- package/dist/LeafModule.mjs.map +1 -0
- package/dist/ProjectRoot.mjs +38 -0
- package/dist/ProjectRoot.mjs.map +1 -0
- package/dist/RelativeModulePath.mjs +13 -0
- package/dist/RelativeModulePath.mjs.map +1 -0
- package/dist/Remove.mjs +24 -0
- package/dist/Remove.mjs.map +1 -0
- package/dist/RestoreWatcher.mjs +31 -0
- package/dist/RestoreWatcher.mjs.map +1 -0
- package/dist/Rollback.mjs +50 -0
- package/dist/Rollback.mjs.map +1 -0
- package/dist/SnapshotError.mjs +21 -0
- package/dist/SnapshotError.mjs.map +1 -0
- package/dist/SpecAssemblyNode.mjs +91 -0
- package/dist/SpecAssemblyNode.mjs.map +1 -0
- package/dist/SpecModulePath.mjs +10 -0
- package/dist/SpecModulePath.mjs.map +1 -0
- package/dist/SyncState.mjs +122 -0
- package/dist/SyncState.mjs.map +1 -0
- package/dist/TableModule.mjs +97 -0
- package/dist/TableModule.mjs.map +1 -0
- package/dist/TableModulePath.mjs +8 -0
- package/dist/TableModulePath.mjs.map +1 -0
- package/dist/WatchBuild.mjs +190 -0
- package/dist/WatchBuild.mjs.map +1 -0
- package/dist/WatchGraph.mjs +35 -0
- package/dist/WatchGraph.mjs.map +1 -0
- package/dist/WatchTopology.mjs +55 -0
- package/dist/WatchTopology.mjs.map +1 -0
- package/dist/Watcher.mjs +377 -0
- package/dist/Watcher.mjs.map +1 -0
- package/dist/cliApp.mjs +9 -0
- package/dist/cliApp.mjs.map +1 -0
- package/dist/confect/codegen.mjs +570 -0
- package/dist/confect/codegen.mjs.map +1 -0
- package/dist/confect/declaration.mjs +219 -0
- package/dist/confect/declaration.mjs.map +1 -0
- package/dist/confect/dev.mjs +182 -0
- package/dist/confect/dev.mjs.map +1 -0
- package/dist/confect.mjs +9 -0
- package/dist/confect.mjs.map +1 -0
- package/dist/index.mjs +19 -0
- package/dist/index.mjs.map +1 -0
- package/dist/log.mjs +107 -0
- package/dist/log.mjs.map +1 -0
- package/dist/package.mjs +6 -0
- package/dist/package.mjs.map +1 -0
- package/dist/templates.mjs +448 -0
- package/dist/templates.mjs.map +1 -0
- package/dist/utils.mjs +105 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +51 -3
package/dist/Watcher.mjs
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { ProjectRoot } from "./ProjectRoot.mjs";
|
|
2
|
+
import { bundleWorkspacePlugin } from "./Bundler.mjs";
|
|
3
|
+
import { ConvexDirectory } from "./ConvexDirectory.mjs";
|
|
4
|
+
import { ConfectDirectory } from "./ConfectDirectory.mjs";
|
|
5
|
+
import "./ConvexConfig.mjs";
|
|
6
|
+
import { Kind, discover, isOptional, parse } from "./EntryPoint.mjs";
|
|
7
|
+
import { add, empty, full, reconcile } from "./SyncState.mjs";
|
|
8
|
+
import { Change, Failure, Outcome, State, captureBarrier, complete, diagnostics, diff, emptyCapture, endRequest, getCompletion, initialProgress, isFresh, joinedWithoutCompletion, makeRequestId, observe, parse as parse$1, request, start, verifyInputs } from "./WatchBuild.mjs";
|
|
9
|
+
import { make as make$1 } from "./WatchTopology.mjs";
|
|
10
|
+
import { make as make$2 } from "./RestoreWatcher.mjs";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as FileSystem from "effect/FileSystem";
|
|
13
|
+
import * as Path from "effect/Path";
|
|
14
|
+
import * as Array from "effect/Array";
|
|
15
|
+
import * as Result from "effect/Result";
|
|
16
|
+
import { pipe } from "effect/Function";
|
|
17
|
+
import * as HashSet from "effect/HashSet";
|
|
18
|
+
import * as Match from "effect/Match";
|
|
19
|
+
import * as Option from "effect/Option";
|
|
20
|
+
import { externalPlugin, loadTsConfig, tsconfigPathsToRegExp } from "bundle-require";
|
|
21
|
+
import * as HashMap from "effect/HashMap";
|
|
22
|
+
import * as Ref from "effect/Ref";
|
|
23
|
+
import * as Scope from "effect/Scope";
|
|
24
|
+
import * as Schema from "effect/Schema";
|
|
25
|
+
import * as esbuild from "esbuild";
|
|
26
|
+
import * as Order from "effect/Order";
|
|
27
|
+
import * as Data from "effect/Data";
|
|
28
|
+
import * as Schedule from "effect/Schedule";
|
|
29
|
+
import * as Clock from "effect/Clock";
|
|
30
|
+
import * as Duration from "effect/Duration";
|
|
31
|
+
import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
|
|
32
|
+
import * as Crypto from "effect/Crypto";
|
|
33
|
+
import * as Hex from "effect/encoding/Hex";
|
|
34
|
+
import * as Deferred from "effect/Deferred";
|
|
35
|
+
import * as Exit from "effect/Exit";
|
|
36
|
+
import * as Queue from "effect/Queue";
|
|
37
|
+
import * as Semaphore from "effect/Semaphore";
|
|
38
|
+
import * as Stream from "effect/Stream";
|
|
39
|
+
//#region src/Watcher.ts
|
|
40
|
+
const COALESCE_QUIESCENCE = Duration.millis(300);
|
|
41
|
+
const COALESCE_MAX_WAIT = Duration.seconds(5);
|
|
42
|
+
const WatcherLifecycle = Data.taggedEnum();
|
|
43
|
+
const RefreshOutcome = Data.taggedEnum();
|
|
44
|
+
const isRefreshSuccessful = (outcome) => RefreshOutcome.$match(outcome, {
|
|
45
|
+
Empty: () => true,
|
|
46
|
+
Observed: ({ outcome: observed }) => Outcome.$match(observed, {
|
|
47
|
+
Succeeded: () => true,
|
|
48
|
+
Failed: () => false
|
|
49
|
+
})
|
|
50
|
+
});
|
|
51
|
+
var OperationError = class extends Schema.TaggedError()("WatcherOperationError", {
|
|
52
|
+
operation: Schema.Literals([
|
|
53
|
+
"create",
|
|
54
|
+
"watch",
|
|
55
|
+
"rebuild",
|
|
56
|
+
"dispose",
|
|
57
|
+
"refresh"
|
|
58
|
+
]),
|
|
59
|
+
cause: Schema.Unknown
|
|
60
|
+
}) {};
|
|
61
|
+
const ReportedBuildFailure = Schema.Struct({ errors: Schema.NonEmptyArray(Schema.Struct({ text: Schema.String })) });
|
|
62
|
+
const parseFailure = Schema.decodeUnknownOption(ReportedBuildFailure);
|
|
63
|
+
const make = Effect.fnUntraced(function* () {
|
|
64
|
+
const signal = yield* Queue.sliding(1);
|
|
65
|
+
const pendingRef = yield* Ref.make(empty);
|
|
66
|
+
const restartQueue = yield* Queue.sliding(1);
|
|
67
|
+
const state = {
|
|
68
|
+
lifecycle: yield* Ref.make(WatcherLifecycle.Uninitialized()),
|
|
69
|
+
observation: yield* Ref.make(State.Initial()),
|
|
70
|
+
lock: yield* Semaphore.make(1),
|
|
71
|
+
topology: yield* make$1(pendingRef),
|
|
72
|
+
declared: yield* Ref.make(false)
|
|
73
|
+
};
|
|
74
|
+
const restartWith = (invalidation) => invalidation.pipe(Effect.andThen(Queue.offer(restartQueue, void 0)), Effect.andThen(Queue.offer(signal, void 0)));
|
|
75
|
+
const restart = restartWith(state.topology.invalidate);
|
|
76
|
+
const restartEntry = (entry) => restartWith(state.topology.invalidateEntry(entry));
|
|
77
|
+
const duringRestoreRef = yield* Ref.make(Effect.void);
|
|
78
|
+
return {
|
|
79
|
+
run: Effect.gen(function* () {
|
|
80
|
+
const structure = yield* make$2(confectStructureWatcher(signal, pendingRef, restart, restartEntry));
|
|
81
|
+
yield* Ref.set(duringRestoreRef, structure.duringRestore);
|
|
82
|
+
yield* Effect.all([
|
|
83
|
+
Effect.scoped(entryPointsWatcher(signal, pendingRef, restartQueue, state)),
|
|
84
|
+
structure.failure,
|
|
85
|
+
convexConfigStructureWatcher(restart, state.declared)
|
|
86
|
+
], { concurrency: "unbounded" });
|
|
87
|
+
}).pipe(Effect.scoped),
|
|
88
|
+
duringRestore: Effect.flatten(Ref.get(duringRestoreRef)),
|
|
89
|
+
discardRestoreEchoes: refresh(state).pipe(Effect.ignore, Effect.andThen(Ref.set(pendingRef, empty))),
|
|
90
|
+
refresh: refresh(state),
|
|
91
|
+
next: Queue.take(signal).pipe(Effect.andThen(drainUntilQuiescent(signal, COALESCE_QUIESCENCE, COALESCE_MAX_WAIT)), Effect.andThen(state.topology.takePending), Effect.onInterrupt(() => Queue.offer(signal, void 0))),
|
|
92
|
+
pending: Ref.get(pendingRef),
|
|
93
|
+
requestRetry: Ref.update(pendingRef, full).pipe(Effect.andThen(Queue.offer(signal, void 0)), Effect.asVoid),
|
|
94
|
+
diagnostics: Ref.get(state.observation).pipe(Effect.map(diagnostics))
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
const drainUntilQuiescent = Effect.fnUntraced(function* (signal, quiescence, maxWait) {
|
|
98
|
+
const start = yield* Clock.currentTimeMillis;
|
|
99
|
+
const maxMillis = Duration.toMillis(maxWait);
|
|
100
|
+
const loop = Effect.gen(function* () {
|
|
101
|
+
yield* Effect.sleep(quiescence);
|
|
102
|
+
if ((yield* Queue.clear(signal)).length === 0) return;
|
|
103
|
+
if ((yield* Clock.currentTimeMillis) - start < maxMillis) yield* loop;
|
|
104
|
+
});
|
|
105
|
+
yield* loop;
|
|
106
|
+
});
|
|
107
|
+
const esbuildOptions = (path, fs, crypto, projectRoot, generatedDirectory, entries, notExternal, stateRef, captureRef, progressRef, signal, pendingRef, initial) => {
|
|
108
|
+
const encodeString = Schema.encodeSync(Schema.fromJsonString(Schema.String));
|
|
109
|
+
return {
|
|
110
|
+
absWorkingDir: projectRoot,
|
|
111
|
+
stdin: {
|
|
112
|
+
contents: entries.map((entry) => `import ${encodeString(entry.absolutePath)};`).join("\n"),
|
|
113
|
+
resolveDir: projectRoot,
|
|
114
|
+
sourcefile: "confect-watch.ts",
|
|
115
|
+
loader: "ts"
|
|
116
|
+
},
|
|
117
|
+
bundle: true,
|
|
118
|
+
write: false,
|
|
119
|
+
metafile: true,
|
|
120
|
+
platform: "node",
|
|
121
|
+
format: "esm",
|
|
122
|
+
logLevel: "silent",
|
|
123
|
+
plugins: [
|
|
124
|
+
bundleWorkspacePlugin(path, fs, notExternal),
|
|
125
|
+
externalPlugin({ notExternal: [...notExternal] }),
|
|
126
|
+
{
|
|
127
|
+
name: "notify-rebuild",
|
|
128
|
+
setup(build) {
|
|
129
|
+
build.onStart(() => Effect.runPromise(Effect.gen(function* () {
|
|
130
|
+
yield* Ref.update(progressRef, start);
|
|
131
|
+
yield* Ref.set(captureRef, emptyCapture);
|
|
132
|
+
}).pipe(Effect.as(void 0))));
|
|
133
|
+
build.onLoad({ filter: /.*/ }, (args) => Effect.runPromise(Effect.gen(function* () {
|
|
134
|
+
const fingerprint = yield* fs.readFile(args.path).pipe(Effect.flatMap((contents) => crypto.digest("SHA-256", contents)), Effect.map(Hex.encode), Effect.result);
|
|
135
|
+
yield* Ref.update(captureRef, (capture) => Result.isSuccess(fingerprint) ? {
|
|
136
|
+
...capture,
|
|
137
|
+
fingerprints: HashMap.set(capture.fingerprints, args.path, fingerprint.success)
|
|
138
|
+
} : {
|
|
139
|
+
...capture,
|
|
140
|
+
failures: HashMap.set(capture.failures, args.path, Failure.InputCaptureFailed({
|
|
141
|
+
file: args.path,
|
|
142
|
+
cause: fingerprint.failure
|
|
143
|
+
}))
|
|
144
|
+
});
|
|
145
|
+
}).pipe(Effect.as(void 0))));
|
|
146
|
+
build.onEnd((result) => Effect.runPromise(Effect.gen(function* () {
|
|
147
|
+
const { generation } = yield* Ref.get(progressRef);
|
|
148
|
+
const previous = yield* Ref.get(stateRef);
|
|
149
|
+
const outcome = yield* parse$1(result, yield* Ref.get(captureRef), (file) => path.resolve(projectRoot, file), crypto);
|
|
150
|
+
const current = observe(previous, outcome);
|
|
151
|
+
yield* Ref.set(stateRef, current);
|
|
152
|
+
const change = diff(previous, current, generatedDirectory + path.sep);
|
|
153
|
+
yield* Ref.update(pendingRef, (pending) => Change.$match(change, {
|
|
154
|
+
Full: () => add(pending, entries, true),
|
|
155
|
+
Affected: ({ paths }) => add(pending, entries.filter((entry) => HashSet.has(paths, entry.inputPath))),
|
|
156
|
+
Recovered: ({ paths }) => reconcile(add(pending, entries.filter((entry) => HashSet.has(paths, entry.inputPath))))
|
|
157
|
+
}));
|
|
158
|
+
yield* Queue.offer(signal, void 0);
|
|
159
|
+
yield* Ref.update(progressRef, (progress) => complete(progress, {
|
|
160
|
+
generation,
|
|
161
|
+
outcome
|
|
162
|
+
}));
|
|
163
|
+
yield* Deferred.succeed(initial, void 0);
|
|
164
|
+
})));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
const entryPointsWatcher = Effect.fnUntraced(function* (signal, pendingRef, restartQueue, watcher) {
|
|
171
|
+
const parentScope = yield* Effect.scope;
|
|
172
|
+
const path = yield* Path.Path;
|
|
173
|
+
const fs = yield* FileSystem.FileSystem;
|
|
174
|
+
const projectRoot = yield* ProjectRoot.get;
|
|
175
|
+
const confectDirectory = yield* ConfectDirectory.get;
|
|
176
|
+
const generatedDirectory = path.join(yield* fs.realPath(confectDirectory), "_generated");
|
|
177
|
+
const crypto = yield* Crypto.Crypto;
|
|
178
|
+
const completedInitial = Deferred.make().pipe(Effect.tap((initial) => Deferred.succeed(initial, void 0)));
|
|
179
|
+
const sync = Effect.gen(function* () {
|
|
180
|
+
const revision = yield* watcher.topology.revision;
|
|
181
|
+
const current = yield* Ref.get(watcher.lifecycle);
|
|
182
|
+
const entries = yield* discover;
|
|
183
|
+
yield* Ref.set(watcher.declared, entries.some(Kind.$is("App")));
|
|
184
|
+
const desiredPaths = HashSet.fromIterable(entries.map((entry) => entry.absolutePath));
|
|
185
|
+
const key = pipe(Array.fromIterable(desiredPaths), Array.sort(Order.String), Array.join("\n"));
|
|
186
|
+
if (WatcherLifecycle.$match(current, {
|
|
187
|
+
Uninitialized: () => false,
|
|
188
|
+
Empty: () => entries.length === 0,
|
|
189
|
+
Active: ({ key: previousKey }) => previousKey === key
|
|
190
|
+
})) {
|
|
191
|
+
const initial = yield* WatcherLifecycle.$match(current, {
|
|
192
|
+
Uninitialized: () => completedInitial,
|
|
193
|
+
Empty: () => completedInitial,
|
|
194
|
+
Active: ({ initial: activeInitial }) => Effect.succeed(activeInitial)
|
|
195
|
+
});
|
|
196
|
+
yield* refreshCurrent(current).pipe(Effect.catchTag("WatcherOperationError", () => Ref.update(pendingRef, full)));
|
|
197
|
+
yield* watcher.topology.reconcile(revision, initial);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
yield* WatcherLifecycle.$match(current, {
|
|
201
|
+
Uninitialized: () => Effect.void,
|
|
202
|
+
Empty: () => Ref.update(pendingRef, full),
|
|
203
|
+
Active: ({ entries: previousEntries, scope }) => Effect.gen(function* () {
|
|
204
|
+
const removedOptional = previousEntries.filter((entry) => isOptional(entry) && !HashSet.has(desiredPaths, entry.absolutePath));
|
|
205
|
+
yield* Ref.update(pendingRef, (pending) => add(full(pending), removedOptional));
|
|
206
|
+
yield* Scope.close(scope, Exit.void);
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
yield* Ref.set(watcher.lifecycle, WatcherLifecycle.Uninitialized());
|
|
210
|
+
yield* Ref.set(watcher.observation, State.Initial());
|
|
211
|
+
if (!Array.isReadonlyArrayNonEmpty(entries)) {
|
|
212
|
+
yield* Ref.set(watcher.lifecycle, WatcherLifecycle.Empty());
|
|
213
|
+
yield* Ref.update(pendingRef, full);
|
|
214
|
+
yield* Queue.offer(signal, void 0);
|
|
215
|
+
const initial = yield* completedInitial;
|
|
216
|
+
yield* watcher.topology.reconcile(revision, initial);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const scope = yield* Scope.fork(parentScope, "sequential");
|
|
220
|
+
const captureRef = yield* Ref.make(emptyCapture);
|
|
221
|
+
const progress = yield* Ref.make(initialProgress);
|
|
222
|
+
const initial = yield* Deferred.make();
|
|
223
|
+
const tsconfig = loadTsConfig(projectRoot);
|
|
224
|
+
const notExternal = tsconfigPathsToRegExp(tsconfig?.data.compilerOptions?.paths ?? {});
|
|
225
|
+
const context = yield* Effect.acquireRelease(Effect.tryPromise({
|
|
226
|
+
try: () => esbuild.context(esbuildOptions(path, fs, crypto, projectRoot, generatedDirectory, entries, notExternal, watcher.observation, captureRef, progress, signal, pendingRef, initial)),
|
|
227
|
+
catch: (cause) => new OperationError({
|
|
228
|
+
operation: "create",
|
|
229
|
+
cause
|
|
230
|
+
})
|
|
231
|
+
}), (ctx) => Effect.tryPromise({
|
|
232
|
+
try: () => ctx.dispose(),
|
|
233
|
+
catch: (cause) => new OperationError({
|
|
234
|
+
operation: "dispose",
|
|
235
|
+
cause
|
|
236
|
+
})
|
|
237
|
+
}).pipe(Effect.orDie)).pipe(Scope.provide(scope));
|
|
238
|
+
const requestIds = /* @__PURE__ */ new WeakMap();
|
|
239
|
+
yield* Ref.set(watcher.lifecycle, WatcherLifecycle.Active({
|
|
240
|
+
initial,
|
|
241
|
+
key,
|
|
242
|
+
scope,
|
|
243
|
+
entries,
|
|
244
|
+
context,
|
|
245
|
+
identifyRequest: (promise) => {
|
|
246
|
+
const existing = requestIds.get(promise);
|
|
247
|
+
if (existing !== void 0) return existing;
|
|
248
|
+
const id = makeRequestId();
|
|
249
|
+
requestIds.set(promise, id);
|
|
250
|
+
return id;
|
|
251
|
+
},
|
|
252
|
+
progress,
|
|
253
|
+
verifyInputs: (snapshot) => verifyInputs(snapshot, fs, crypto)
|
|
254
|
+
}));
|
|
255
|
+
yield* Effect.tryPromise({
|
|
256
|
+
try: () => context.watch(),
|
|
257
|
+
catch: (cause) => new OperationError({
|
|
258
|
+
operation: "watch",
|
|
259
|
+
cause
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
yield* watcher.topology.reconcile(revision, initial);
|
|
263
|
+
}).pipe(Semaphore.withPermit(watcher.lock));
|
|
264
|
+
yield* sync;
|
|
265
|
+
return yield* Effect.forever(Queue.take(restartQueue).pipe(Effect.andThen(sync)));
|
|
266
|
+
}, Effect.provide(NodeCrypto.layer));
|
|
267
|
+
const refreshCurrent = Effect.fnUntraced(function* (current) {
|
|
268
|
+
return yield* WatcherLifecycle.$match(current, {
|
|
269
|
+
Empty: () => Effect.succeed(RefreshOutcome.Empty()),
|
|
270
|
+
Uninitialized: () => Effect.fail(new OperationError({
|
|
271
|
+
operation: "refresh",
|
|
272
|
+
cause: "The dependency watcher is not initialized"
|
|
273
|
+
})),
|
|
274
|
+
Active: ({ context, identifyRequest, progress, verifyInputs }) => Effect.gen(function* () {
|
|
275
|
+
const runSync = Effect.runSyncWith(yield* Effect.context());
|
|
276
|
+
const barrier = captureBarrier(yield* Ref.get(progress));
|
|
277
|
+
const completed = yield* Effect.gen(function* () {
|
|
278
|
+
const built = yield* Effect.tryPromise({
|
|
279
|
+
try: () => {
|
|
280
|
+
const promise = context.rebuild();
|
|
281
|
+
runSync(Ref.update(progress, (currentProgress) => request(currentProgress, identifyRequest(promise))));
|
|
282
|
+
return promise;
|
|
283
|
+
},
|
|
284
|
+
catch: (cause) => new OperationError({
|
|
285
|
+
operation: "rebuild",
|
|
286
|
+
cause
|
|
287
|
+
})
|
|
288
|
+
}).pipe(Effect.result);
|
|
289
|
+
const currentProgress = yield* Ref.get(progress);
|
|
290
|
+
const completed = getCompletion(currentProgress);
|
|
291
|
+
if (Result.isFailure(built)) {
|
|
292
|
+
const rejected = parseFailure(built.failure.cause);
|
|
293
|
+
if (Option.isNone(rejected)) return yield* built.failure;
|
|
294
|
+
if (joinedWithoutCompletion(currentProgress)) return Option.none();
|
|
295
|
+
if (Option.isNone(completed) || !Outcome.$is("Failed")(completed.value.outcome)) return yield* new OperationError({
|
|
296
|
+
operation: "rebuild",
|
|
297
|
+
cause: rejected.value.errors
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
if (joinedWithoutCompletion(currentProgress)) return Option.none();
|
|
301
|
+
const observed = yield* Effect.fromOption(completed).pipe(Effect.mapError(() => new OperationError({
|
|
302
|
+
operation: "rebuild",
|
|
303
|
+
cause: "esbuild completed without a build observation"
|
|
304
|
+
})));
|
|
305
|
+
if (isFresh(barrier, observed) && Outcome.$is("Succeeded")(observed.outcome)) {
|
|
306
|
+
if (!(yield* verifyInputs(observed.outcome.snapshot).pipe(Effect.mapError(({ cause }) => new OperationError({
|
|
307
|
+
operation: "refresh",
|
|
308
|
+
cause
|
|
309
|
+
}))))) return Option.none();
|
|
310
|
+
}
|
|
311
|
+
return Option.some(observed);
|
|
312
|
+
}).pipe(Effect.ensuring(Ref.update(progress, endRequest))).pipe(Effect.repeat({ while: (observed) => Option.isNone(observed) || !isFresh(barrier, observed.value) }), Effect.flatMap((observed) => Effect.fromOption(observed).pipe(Effect.orDie)));
|
|
313
|
+
return RefreshOutcome.Observed({ outcome: completed.outcome });
|
|
314
|
+
})
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
const refresh = (watcher) => watcher.lock.withPermit(Ref.get(watcher.lifecycle).pipe(Effect.flatMap(refreshCurrent)));
|
|
318
|
+
const confectStructureWatcher = Effect.fnUntraced(function* (signal, pendingRef, restart, restartEntry) {
|
|
319
|
+
const fs = yield* FileSystem.FileSystem;
|
|
320
|
+
const path = yield* Path.Path;
|
|
321
|
+
const confectDirectory = yield* ConfectDirectory.get;
|
|
322
|
+
const removedDirectory = Schema.Struct({
|
|
323
|
+
code: Schema.Literal("ENOENT"),
|
|
324
|
+
syscall: Schema.Literal("scandir"),
|
|
325
|
+
path: Schema.String
|
|
326
|
+
});
|
|
327
|
+
yield* pipe(fs.watch(confectDirectory, { recursive: true }), Stream.runForEach((event) => handleConfectChange({
|
|
328
|
+
relativePath: path.relative(confectDirectory, path.resolve(confectDirectory, event.path)),
|
|
329
|
+
eventTag: event._tag,
|
|
330
|
+
signal,
|
|
331
|
+
pendingRef,
|
|
332
|
+
restart,
|
|
333
|
+
restartEntry
|
|
334
|
+
})), Effect.retry({
|
|
335
|
+
schedule: Schedule.spaced("10 millis"),
|
|
336
|
+
while: (error) => Effect.gen(function* () {
|
|
337
|
+
const removed = Schema.decodeUnknownOption(removedDirectory)(error.reason.cause);
|
|
338
|
+
if (Option.isNone(removed)) return false;
|
|
339
|
+
const relative = path.relative(confectDirectory, removed.value.path);
|
|
340
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) return false;
|
|
341
|
+
if (!(yield* fs.exists(confectDirectory).pipe(Effect.orElseSucceed(() => false)))) return false;
|
|
342
|
+
yield* restart;
|
|
343
|
+
return true;
|
|
344
|
+
})
|
|
345
|
+
}));
|
|
346
|
+
});
|
|
347
|
+
/**
|
|
348
|
+
* Non-recursive `fs.watch` on the convex directory, reacting only to
|
|
349
|
+
* `convex.config.ts`. Recursion is deliberately avoided: codegen (Confect's and
|
|
350
|
+
* Convex's) writes into `convex/` and `convex/_generated/` constantly, and
|
|
351
|
+
* reacting to those writes would loop. Create/Remove offers to `restartQueue`
|
|
352
|
+
* so the entry-point watcher set picks up (or drops) the config's esbuild
|
|
353
|
+
* watcher.
|
|
354
|
+
*/
|
|
355
|
+
const convexConfigStructureWatcher = Effect.fnUntraced(function* (restart, declared) {
|
|
356
|
+
const fs = yield* FileSystem.FileSystem;
|
|
357
|
+
const path = yield* Path.Path;
|
|
358
|
+
const convexDirectory = yield* ConvexDirectory.get;
|
|
359
|
+
yield* pipe(fs.watch(convexDirectory), Stream.runForEach((event) => Effect.gen(function* () {
|
|
360
|
+
if (path.relative(convexDirectory, event.path) !== "convex.config.ts" || (yield* Ref.get(declared))) return;
|
|
361
|
+
yield* Match.value(event).pipe(Match.tag("Update", () => Effect.void), Match.tag("Create", "Remove", () => restart), Match.exhaustive);
|
|
362
|
+
})));
|
|
363
|
+
});
|
|
364
|
+
const flipDirtyAndSignal = (pendingRef, signal, restart, isLifecycleChange) => isLifecycleChange ? restart : Ref.update(pendingRef, full).pipe(Effect.andThen(Queue.offer(signal, void 0)));
|
|
365
|
+
const handleConfectChange = ({ relativePath, eventTag, signal, pendingRef, restart, restartEntry }) => {
|
|
366
|
+
if (relativePath.split(/[/\\]/).includes("_generated")) return Effect.void;
|
|
367
|
+
if (!relativePath.endsWith(".ts")) return Effect.void;
|
|
368
|
+
const isLifecycleChange = Match.value(eventTag).pipe(Match.when("Update", () => false), Match.whenOr("Create", "Remove", () => true), Match.exhaustive);
|
|
369
|
+
const entry = parse(relativePath);
|
|
370
|
+
if (Option.isSome(entry)) return isLifecycleChange ? restartEntry(entry.value) : Effect.void;
|
|
371
|
+
if (relativePath === "schema.ts") return flipDirtyAndSignal(pendingRef, signal, restart, isLifecycleChange);
|
|
372
|
+
return Match.value(eventTag).pipe(Match.when("Create", () => flipDirtyAndSignal(pendingRef, signal, restart, false)), Match.whenOr("Update", "Remove", () => Effect.void), Match.exhaustive);
|
|
373
|
+
};
|
|
374
|
+
//#endregion
|
|
375
|
+
export { OperationError, isRefreshSuccessful, make, parseFailure };
|
|
376
|
+
|
|
377
|
+
//# sourceMappingURL=Watcher.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Watcher.mjs","names":["SyncState.empty","WatchTopology.make","RestoreWatcher.make","SyncState.full","WatchBuild.diagnostics","Bundler.bundleWorkspacePlugin","WatchBuild.start","WatchBuild.emptyCapture","WatchBuild.parse","WatchBuild.observe","WatchBuild.diff","SyncState.add","SyncState.reconcile","WatchBuild.complete","EntryPoint.discover","EntryPoint.isOptional","WatchBuild.initialProgress","WatchBuild.makeRequestId","WatchBuild.verifyInputs","WatchBuild.captureBarrier","WatchBuild.request","WatchBuild.getCompletion","WatchBuild.joinedWithoutCompletion","WatchBuild.isFresh","WatchBuild.endRequest","EntryPoint.parse"],"sources":["../src/Watcher.ts"],"sourcesContent":["import * as Clock from \"effect/Clock\";\nimport * as Duration from \"effect/Duration\";\nimport * as NodeCrypto from \"@effect/platform-node/NodeCrypto\";\nimport * as Crypto from \"effect/Crypto\";\nimport * as Hex from \"effect/encoding/Hex\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Path from \"effect/Path\";\nimport { pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Data from \"effect/Data\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Exit from \"effect/Exit\";\nimport * as HashSet from \"effect/HashSet\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as Match from \"effect/Match\";\nimport * as Option from \"effect/Option\";\nimport * as Order from \"effect/Order\";\nimport * as Queue from \"effect/Queue\";\nimport * as Ref from \"effect/Ref\";\nimport * as Result from \"effect/Result\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport * as Scope from \"effect/Scope\";\nimport * as Schema from \"effect/Schema\";\nimport * as Schedule from \"effect/Schedule\";\nimport * as Stream from \"effect/Stream\";\nimport {\n externalPlugin,\n loadTsConfig,\n tsconfigPathsToRegExp,\n} from \"bundle-require\";\nimport * as esbuild from \"esbuild\";\nimport * as Bundler from \"./Bundler.js\";\nimport * as WatchBuild from \"./WatchBuild.js\";\nimport * as WatchTopology from \"./WatchTopology.js\";\nimport * as SyncState from \"./SyncState.js\";\nimport type { Pending } from \"./SyncState.js\";\nimport * as EntryPoint from \"./EntryPoint.js\";\nimport type { EntryPoint as Entry } from \"./EntryPoint.js\";\nimport { ConfectDirectory } from \"./ConfectDirectory.js\";\nimport { CONVEX_CONFIG_FILENAME } from \"./ConvexConfig.js\";\nimport { ConvexDirectory } from \"./ConvexDirectory.js\";\nimport { ProjectRoot } from \"./ProjectRoot.js\";\nimport * as RestoreWatcher from \"./RestoreWatcher.js\";\n\nconst COALESCE_QUIESCENCE = Duration.millis(300);\n\n// Upper bound on `drainUntilQuiescent` so a pathological infinite\n// signal stream can't pin the sync loop forever.\nconst COALESCE_MAX_WAIT = Duration.seconds(5);\n\ntype WatcherLifecycle = Data.TaggedEnum<{\n Uninitialized: {};\n Empty: {};\n Active: {\n readonly initial: Deferred.Deferred<void>;\n readonly key: string;\n readonly scope: Scope.Closeable;\n readonly entries: Array.NonEmptyReadonlyArray<Entry>;\n readonly context: esbuild.BuildContext;\n readonly identifyRequest: (\n promise: Promise<esbuild.BuildResult>,\n ) => WatchBuild.RequestId;\n readonly progress: Ref.Ref<WatchBuild.Progress>;\n readonly verifyInputs: (\n snapshot: WatchBuild.Snapshot,\n ) => ReturnType<typeof WatchBuild.verifyInputs>;\n };\n}>;\nconst WatcherLifecycle = Data.taggedEnum<WatcherLifecycle>();\n\ninterface State {\n readonly lifecycle: Ref.Ref<WatcherLifecycle>;\n readonly observation: Ref.Ref<WatchBuild.State>;\n readonly lock: Semaphore.Semaphore;\n readonly topology: WatchTopology.WatchTopology;\n // Whether the last discovery found `confect/app.ts`.\n readonly declared: Ref.Ref<boolean>;\n}\n\ntype RefreshOutcome = Data.TaggedEnum<{\n Empty: {};\n Observed: { readonly outcome: WatchBuild.Outcome };\n}>;\nconst RefreshOutcome = Data.taggedEnum<RefreshOutcome>();\n\nexport const isRefreshSuccessful = (outcome: RefreshOutcome): boolean =>\n RefreshOutcome.$match(outcome, {\n Empty: () => true,\n Observed: ({ outcome: observed }) =>\n WatchBuild.Outcome.$match(observed, {\n Succeeded: () => true,\n Failed: () => false,\n }),\n });\n\nexport class OperationError extends Schema.TaggedError<OperationError>()(\n \"WatcherOperationError\",\n {\n operation: Schema.Literals([\n \"create\",\n \"watch\",\n \"rebuild\",\n \"dispose\",\n \"refresh\",\n ]),\n cause: Schema.Unknown,\n },\n) {}\n\nconst ReportedBuildFailure = Schema.Struct({\n errors: Schema.NonEmptyArray(Schema.Struct({ text: Schema.String })),\n});\nexport const parseFailure = Schema.decodeUnknownOption(ReportedBuildFailure);\n\nexport const make = Effect.fnUntraced(function* () {\n const signal = yield* Queue.sliding<void>(1);\n const pendingRef = yield* Ref.make<Pending>(SyncState.empty);\n const restartQueue = yield* Queue.sliding<void>(1);\n const state: State = {\n lifecycle: yield* Ref.make<WatcherLifecycle>(\n WatcherLifecycle.Uninitialized(),\n ),\n observation: yield* Ref.make<WatchBuild.State>(WatchBuild.State.Initial()),\n lock: yield* Semaphore.make(1),\n topology: yield* WatchTopology.make(pendingRef),\n declared: yield* Ref.make(false),\n };\n const restartWith = (invalidation: Effect.Effect<void>) =>\n invalidation.pipe(\n Effect.andThen(Queue.offer(restartQueue, undefined)),\n Effect.andThen(Queue.offer(signal, undefined)),\n );\n const restart = restartWith(state.topology.invalidate);\n const restartEntry = (entry: EntryPoint.Kind) =>\n restartWith(state.topology.invalidateEntry(entry));\n const duringRestoreRef = yield* Ref.make<\n Effect.Effect<void, never, Scope.Scope>\n >(Effect.void);\n return {\n run: Effect.gen(function* () {\n const structure = yield* RestoreWatcher.make(\n confectStructureWatcher(signal, pendingRef, restart, restartEntry),\n );\n yield* Ref.set(duringRestoreRef, structure.duringRestore);\n yield* Effect.all(\n [\n Effect.scoped(\n entryPointsWatcher(signal, pendingRef, restartQueue, state),\n ),\n structure.failure,\n convexConfigStructureWatcher(restart, state.declared),\n ],\n { concurrency: \"unbounded\" },\n );\n }).pipe(Effect.scoped),\n duringRestore: Effect.flatten(Ref.get(duringRestoreRef)),\n // Restored output makes esbuild rebuild; observe that, then drop the work\n // it queued so the restore does not trigger another generation.\n discardRestoreEchoes: refresh(state).pipe(\n Effect.ignore,\n Effect.andThen(Ref.set(pendingRef, SyncState.empty)),\n ),\n refresh: refresh(state),\n next: Queue.take(signal).pipe(\n Effect.andThen(\n drainUntilQuiescent(signal, COALESCE_QUIESCENCE, COALESCE_MAX_WAIT),\n ),\n Effect.andThen(state.topology.takePending),\n Effect.onInterrupt(() => Queue.offer(signal, undefined)),\n ),\n pending: Ref.get(pendingRef),\n requestRetry: Ref.update(pendingRef, SyncState.full).pipe(\n Effect.andThen(Queue.offer(signal, undefined)),\n Effect.asVoid,\n ),\n diagnostics: Ref.get(state.observation).pipe(\n Effect.map(WatchBuild.diagnostics),\n ),\n } as const;\n});\n\nexport type Watcher = Effect.Success<ReturnType<typeof make>>;\n\nconst drainUntilQuiescent = Effect.fnUntraced(function* (\n signal: Queue.Queue<void>,\n quiescence: Duration.Duration,\n maxWait: Duration.Duration,\n) {\n const start = yield* Clock.currentTimeMillis;\n const maxMillis = Duration.toMillis(maxWait);\n const loop: Effect.Effect<void> = Effect.gen(function* () {\n yield* Effect.sleep(quiescence);\n const drained = yield* Queue.clear(signal);\n if (drained.length === 0) return;\n const now = yield* Clock.currentTimeMillis;\n if (now - start < maxMillis) {\n yield* loop;\n }\n });\n yield* loop;\n});\n\nconst esbuildOptions = (\n path: Path.Path,\n fs: FileSystem.FileSystem,\n crypto: Crypto.Crypto,\n projectRoot: string,\n generatedDirectory: string,\n entries: ReadonlyArray<Entry>,\n notExternal: ReadonlyArray<RegExp>,\n stateRef: Ref.Ref<WatchBuild.State>,\n captureRef: Ref.Ref<WatchBuild.Capture>,\n progressRef: Ref.Ref<WatchBuild.Progress>,\n signal: Queue.Queue<void>,\n pendingRef: Ref.Ref<Pending>,\n initial: Deferred.Deferred<void>,\n): esbuild.BuildOptions => {\n const encodeString = Schema.encodeSync(Schema.fromJsonString(Schema.String));\n return {\n absWorkingDir: projectRoot,\n stdin: {\n contents: entries\n .map((entry) => `import ${encodeString(entry.absolutePath)};`)\n .join(\"\\n\"),\n resolveDir: projectRoot,\n sourcefile: \"confect-watch.ts\",\n loader: \"ts\",\n },\n bundle: true,\n write: false,\n metafile: true,\n platform: \"node\",\n format: \"esm\",\n logLevel: \"silent\",\n plugins: [\n Bundler.bundleWorkspacePlugin(path, fs, notExternal),\n externalPlugin({ notExternal: [...notExternal] }),\n {\n name: \"notify-rebuild\",\n setup(build) {\n build.onStart(() =>\n Effect.runPromise(\n Effect.gen(function* () {\n yield* Ref.update(progressRef, WatchBuild.start);\n yield* Ref.set(captureRef, WatchBuild.emptyCapture);\n }).pipe(Effect.as(undefined)),\n ),\n );\n build.onLoad({ filter: /.*/ }, (args) =>\n Effect.runPromise(\n Effect.gen(function* () {\n const fingerprint = yield* fs.readFile(args.path).pipe(\n Effect.flatMap((contents) =>\n crypto.digest(\"SHA-256\", contents),\n ),\n Effect.map(Hex.encode),\n Effect.result,\n );\n yield* Ref.update(captureRef, (capture) =>\n Result.isSuccess(fingerprint)\n ? {\n ...capture,\n fingerprints: HashMap.set(\n capture.fingerprints,\n args.path,\n fingerprint.success,\n ),\n }\n : {\n ...capture,\n failures: HashMap.set(\n capture.failures,\n args.path,\n WatchBuild.Failure.InputCaptureFailed({\n file: args.path,\n cause: fingerprint.failure,\n }),\n ),\n },\n );\n }).pipe(Effect.as(undefined)),\n ),\n );\n build.onEnd((result) =>\n Effect.runPromise(\n Effect.gen(function* () {\n const { generation } = yield* Ref.get(progressRef);\n const previous = yield* Ref.get(stateRef);\n const outcome = yield* WatchBuild.parse(\n result,\n yield* Ref.get(captureRef),\n (file) => path.resolve(projectRoot, file),\n crypto,\n );\n const current = WatchBuild.observe(previous, outcome);\n yield* Ref.set(stateRef, current);\n const change = WatchBuild.diff(\n previous,\n current,\n generatedDirectory + path.sep,\n );\n yield* Ref.update(pendingRef, (pending) =>\n WatchBuild.Change.$match(change, {\n Full: () => SyncState.add(pending, entries, true),\n Affected: ({ paths }) =>\n SyncState.add(\n pending,\n entries.filter((entry) =>\n HashSet.has(paths, entry.inputPath),\n ),\n ),\n Recovered: ({ paths }) =>\n SyncState.reconcile(\n SyncState.add(\n pending,\n entries.filter((entry) =>\n HashSet.has(paths, entry.inputPath),\n ),\n ),\n ),\n }),\n );\n yield* Queue.offer(signal, undefined);\n yield* Ref.update(progressRef, (progress) =>\n WatchBuild.complete(progress, { generation, outcome }),\n );\n yield* Deferred.succeed(initial, undefined);\n }),\n ),\n );\n },\n },\n ],\n };\n};\n\nconst entryPointsWatcher = Effect.fnUntraced(function* (\n signal: Queue.Queue<void>,\n pendingRef: Ref.Ref<Pending>,\n restartQueue: Queue.Queue<void>,\n watcher: State,\n) {\n const parentScope = yield* Effect.scope;\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n const projectRoot = yield* ProjectRoot.get;\n const confectDirectory = yield* ConfectDirectory.get;\n const generatedDirectory = path.join(\n yield* fs.realPath(confectDirectory),\n \"_generated\",\n );\n const crypto = yield* Crypto.Crypto;\n const completedInitial = Deferred.make<void>().pipe(\n Effect.tap((initial) => Deferred.succeed(initial, undefined)),\n );\n\n const sync = Effect.gen(function* () {\n const revision = yield* watcher.topology.revision;\n const current = yield* Ref.get(watcher.lifecycle);\n const entries = yield* EntryPoint.discover;\n yield* Ref.set(watcher.declared, entries.some(EntryPoint.Kind.$is(\"App\")));\n const desiredPaths = HashSet.fromIterable(\n entries.map((entry) => entry.absolutePath),\n );\n const key = pipe(\n Array.fromIterable(desiredPaths),\n Array.sort(Order.String),\n Array.join(\"\\n\"),\n );\n const unchanged = WatcherLifecycle.$match(current, {\n Uninitialized: () => false,\n Empty: () => entries.length === 0,\n Active: ({ key: previousKey }) => previousKey === key,\n });\n if (unchanged) {\n const initial = yield* WatcherLifecycle.$match(current, {\n Uninitialized: () => completedInitial,\n Empty: () => completedInitial,\n Active: ({ initial: activeInitial }) => Effect.succeed(activeInitial),\n });\n yield* refreshCurrent(current).pipe(\n Effect.catchTag(\"WatcherOperationError\", () =>\n Ref.update(pendingRef, SyncState.full),\n ),\n );\n yield* watcher.topology.reconcile(revision, initial);\n return;\n }\n yield* WatcherLifecycle.$match(current, {\n Uninitialized: () => Effect.void,\n Empty: () => Ref.update(pendingRef, SyncState.full),\n Active: ({ entries: previousEntries, scope }) =>\n Effect.gen(function* () {\n const removedOptional = previousEntries.filter(\n (entry) =>\n EntryPoint.isOptional(entry) &&\n !HashSet.has(desiredPaths, entry.absolutePath),\n );\n yield* Ref.update(pendingRef, (pending) =>\n SyncState.add(SyncState.full(pending), removedOptional),\n );\n yield* Scope.close(scope, Exit.void);\n }),\n });\n yield* Ref.set(watcher.lifecycle, WatcherLifecycle.Uninitialized());\n yield* Ref.set(watcher.observation, WatchBuild.State.Initial());\n if (!Array.isReadonlyArrayNonEmpty(entries)) {\n yield* Ref.set(watcher.lifecycle, WatcherLifecycle.Empty());\n yield* Ref.update(pendingRef, SyncState.full);\n yield* Queue.offer(signal, undefined);\n const initial = yield* completedInitial;\n yield* watcher.topology.reconcile(revision, initial);\n return;\n }\n\n const scope = yield* Scope.fork(parentScope, \"sequential\");\n const captureRef = yield* Ref.make(WatchBuild.emptyCapture);\n const progress = yield* Ref.make(WatchBuild.initialProgress);\n const initial = yield* Deferred.make<void>();\n const tsconfig = loadTsConfig(projectRoot);\n const notExternal = tsconfigPathsToRegExp(\n tsconfig?.data.compilerOptions?.paths ?? {},\n );\n const context = yield* Effect.acquireRelease(\n Effect.tryPromise({\n try: () =>\n esbuild.context(\n esbuildOptions(\n path,\n fs,\n crypto,\n projectRoot,\n generatedDirectory,\n entries,\n notExternal,\n watcher.observation,\n captureRef,\n progress,\n signal,\n pendingRef,\n initial,\n ),\n ),\n catch: (cause) => new OperationError({ operation: \"create\", cause }),\n }),\n (ctx) =>\n Effect.tryPromise({\n try: () => ctx.dispose(),\n catch: (cause) => new OperationError({ operation: \"dispose\", cause }),\n }).pipe(Effect.orDie),\n ).pipe(Scope.provide(scope));\n const requestIds = new WeakMap<\n Promise<esbuild.BuildResult>,\n WatchBuild.RequestId\n >();\n yield* Ref.set(\n watcher.lifecycle,\n WatcherLifecycle.Active({\n initial,\n key,\n scope,\n entries,\n context,\n identifyRequest: (promise) => {\n const existing = requestIds.get(promise);\n if (existing !== undefined) return existing;\n const id = WatchBuild.makeRequestId();\n requestIds.set(promise, id);\n return id;\n },\n progress,\n verifyInputs: (snapshot) =>\n WatchBuild.verifyInputs(snapshot, fs, crypto),\n }),\n );\n yield* Effect.tryPromise({\n try: () => context.watch(),\n catch: (cause) => new OperationError({ operation: \"watch\", cause }),\n });\n yield* watcher.topology.reconcile(revision, initial);\n }).pipe(Semaphore.withPermit(watcher.lock));\n\n yield* sync;\n return yield* Effect.forever(\n Queue.take(restartQueue).pipe(Effect.andThen(sync)),\n );\n}, Effect.provide(NodeCrypto.layer));\n\nconst refreshCurrent = Effect.fnUntraced(function* (current: WatcherLifecycle) {\n return yield* WatcherLifecycle.$match(current, {\n Empty: () => Effect.succeed(RefreshOutcome.Empty()),\n Uninitialized: () =>\n Effect.fail(\n new OperationError({\n operation: \"refresh\",\n cause: \"The dependency watcher is not initialized\",\n }),\n ),\n Active: ({ context, identifyRequest, progress, verifyInputs }) =>\n Effect.gen(function* () {\n const runSync = Effect.runSyncWith(yield* Effect.context());\n const barrier = WatchBuild.captureBarrier(yield* Ref.get(progress));\n const rebuild = Effect.gen(function* () {\n const built = yield* Effect.tryPromise({\n try: () => {\n const promise = context.rebuild();\n runSync(\n Ref.update(progress, (currentProgress) =>\n WatchBuild.request(currentProgress, identifyRequest(promise)),\n ),\n );\n return promise;\n },\n catch: (cause) =>\n new OperationError({ operation: \"rebuild\", cause }),\n }).pipe(Effect.result);\n const currentProgress = yield* Ref.get(progress);\n const completed = WatchBuild.getCompletion(currentProgress);\n if (Result.isFailure(built)) {\n const rejected = parseFailure(built.failure.cause);\n if (Option.isNone(rejected)) return yield* built.failure;\n if (WatchBuild.joinedWithoutCompletion(currentProgress))\n return Option.none<WatchBuild.Completion>();\n if (\n Option.isNone(completed) ||\n !WatchBuild.Outcome.$is(\"Failed\")(completed.value.outcome)\n )\n return yield* new OperationError({\n operation: \"rebuild\",\n cause: rejected.value.errors,\n });\n }\n if (WatchBuild.joinedWithoutCompletion(currentProgress))\n return Option.none<WatchBuild.Completion>();\n const observed = yield* Effect.fromOption(completed).pipe(\n Effect.mapError(\n () =>\n new OperationError({\n operation: \"rebuild\",\n cause: \"esbuild completed without a build observation\",\n }),\n ),\n );\n if (\n WatchBuild.isFresh(barrier, observed) &&\n WatchBuild.Outcome.$is(\"Succeeded\")(observed.outcome)\n ) {\n const unchanged = yield* verifyInputs(\n observed.outcome.snapshot,\n ).pipe(\n Effect.mapError(\n ({ cause }) =>\n new OperationError({ operation: \"refresh\", cause }),\n ),\n );\n if (!unchanged) return Option.none<WatchBuild.Completion>();\n }\n return Option.some(observed);\n }).pipe(Effect.ensuring(Ref.update(progress, WatchBuild.endRequest)));\n const completed = yield* rebuild.pipe(\n Effect.repeat({\n while: (observed) =>\n Option.isNone(observed) ||\n !WatchBuild.isFresh(barrier, observed.value),\n }),\n Effect.flatMap((observed) =>\n Effect.fromOption(observed).pipe(Effect.orDie),\n ),\n );\n return RefreshOutcome.Observed({ outcome: completed.outcome });\n }),\n });\n});\n\nconst refresh = (watcher: State) =>\n watcher.lock.withPermit(\n Ref.get(watcher.lifecycle).pipe(Effect.flatMap(refreshCurrent)),\n );\n\nconst confectStructureWatcher = Effect.fnUntraced(function* (\n signal: Queue.Queue<void>,\n pendingRef: Ref.Ref<Pending>,\n restart: Effect.Effect<unknown>,\n restartEntry: (entry: EntryPoint.Kind) => Effect.Effect<unknown>,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const confectDirectory = yield* ConfectDirectory.get;\n const removedDirectory = Schema.Struct({\n code: Schema.Literal(\"ENOENT\"),\n syscall: Schema.Literal(\"scandir\"),\n path: Schema.String,\n });\n\n yield* pipe(\n fs.watch(confectDirectory, { recursive: true }),\n Stream.runForEach((event) =>\n handleConfectChange({\n relativePath: path.relative(\n confectDirectory,\n path.resolve(confectDirectory, event.path),\n ),\n eventTag: event._tag,\n signal,\n pendingRef,\n restart,\n restartEntry,\n }),\n ),\n Effect.retry({\n schedule: Schedule.spaced(\"10 millis\"),\n while: (error) =>\n Effect.gen(function* () {\n const removed = Schema.decodeUnknownOption(removedDirectory)(\n error.reason.cause,\n );\n if (Option.isNone(removed)) return false;\n const relative = path.relative(confectDirectory, removed.value.path);\n if (\n relative === \"\" ||\n relative === \"..\" ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n )\n return false;\n if (\n !(yield* fs\n .exists(confectDirectory)\n .pipe(Effect.orElseSucceed(() => false)))\n ) {\n return false;\n }\n yield* restart;\n return true;\n }),\n }),\n );\n});\n\n/**\n * Non-recursive `fs.watch` on the convex directory, reacting only to\n * `convex.config.ts`. Recursion is deliberately avoided: codegen (Confect's and\n * Convex's) writes into `convex/` and `convex/_generated/` constantly, and\n * reacting to those writes would loop. Create/Remove offers to `restartQueue`\n * so the entry-point watcher set picks up (or drops) the config's esbuild\n * watcher.\n */\nconst convexConfigStructureWatcher = Effect.fnUntraced(function* (\n restart: Effect.Effect<unknown>,\n declared: Ref.Ref<boolean>,\n) {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const convexDirectory = yield* ConvexDirectory.get;\n\n yield* pipe(\n fs.watch(convexDirectory),\n Stream.runForEach((event) =>\n Effect.gen(function* () {\n // A declared backend's config is codegen output; reacting to its\n // writes would rerun codegen for nothing.\n if (\n path.relative(convexDirectory, event.path) !==\n CONVEX_CONFIG_FILENAME ||\n (yield* Ref.get(declared))\n )\n return;\n yield* Match.value(event).pipe(\n Match.tag(\"Update\", () => Effect.void),\n Match.tag(\"Create\", \"Remove\", () => restart),\n Match.exhaustive,\n );\n }),\n ),\n );\n});\n\nconst flipDirtyAndSignal = (\n pendingRef: Ref.Ref<Pending>,\n signal: Queue.Queue<void>,\n restart: Effect.Effect<unknown>,\n isLifecycleChange: boolean,\n) =>\n isLifecycleChange\n ? restart\n : Ref.update(pendingRef, SyncState.full).pipe(\n Effect.andThen(Queue.offer(signal, undefined)),\n );\n\nconst handleConfectChange = ({\n relativePath,\n eventTag,\n signal,\n pendingRef,\n restart,\n restartEntry,\n}: {\n relativePath: string;\n eventTag: \"Create\" | \"Update\" | \"Remove\";\n signal: Queue.Queue<void>;\n pendingRef: Ref.Ref<Pending>;\n restart: Effect.Effect<unknown>;\n restartEntry: (entry: EntryPoint.Kind) => Effect.Effect<unknown>;\n}) => {\n if (relativePath.split(/[/\\\\]/).includes(\"_generated\")) {\n return Effect.void;\n }\n\n if (!relativePath.endsWith(\".ts\")) {\n return Effect.void;\n }\n\n const isLifecycleChange = Match.value(eventTag).pipe(\n Match.when(\"Update\", () => false),\n Match.whenOr(\"Create\", \"Remove\", () => true),\n Match.exhaustive,\n );\n\n const entry = EntryPoint.parse(relativePath);\n if (Option.isSome(entry)) {\n return isLifecycleChange ? restartEntry(entry.value) : Effect.void;\n }\n\n // A stray `confect/schema.ts` (now codegen-owned at\n // `_generated/schema.ts`) shouldn't exist; flagging it here ensures the\n // next codegen pass surfaces the migration error\n // (`LegacySchemaFileError`) instead of silently ignoring the file.\n if (relativePath === \"schema.ts\") {\n return flipDirtyAndSignal(pendingRef, signal, restart, isLifecycleChange);\n }\n\n // Any other `.ts` under `confect/` (helpers like `tables/notes.ts`).\n // Updates to such files are handled by the esbuild watcher for whichever\n // entry point imports them—its onEnd flips the right dirty flag.\n // Creates are our safety net: when a previously-missing import is added,\n // esbuild may not have its parent directory on a poll path, so we\n // re-run codegen on Create here.\n return Match.value(eventTag).pipe(\n Match.when(\"Create\", () =>\n flipDirtyAndSignal(pendingRef, signal, restart, false),\n ),\n Match.whenOr(\"Update\", \"Remove\", () => Effect.void),\n Match.exhaustive,\n );\n};\n"],"mappings":"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"}
|
package/dist/cliApp.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { version } from "./package.mjs";
|
|
2
|
+
import { confect } from "./confect.mjs";
|
|
3
|
+
import * as Command from "effect/cli/Command";
|
|
4
|
+
//#region src/cliApp.ts
|
|
5
|
+
const cliApp = Command.run(confect, { version });
|
|
6
|
+
//#endregion
|
|
7
|
+
export { cliApp };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=cliApp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cliApp.mjs","names":["packageJson.version"],"sources":["../src/cliApp.ts"],"sourcesContent":["import * as Command from \"effect/cli/Command\";\nimport packageJson from \"../package.json\" with { type: \"json\" };\nimport { confect } from \"./confect.js\";\n\nexport const cliApp = Command.run(confect, {\n version: packageJson.version,\n});\n"],"mappings":";;;;AAIA,MAAa,SAAS,QAAQ,IAAI,SAAS,EAChCA,QACX,CAAC"}
|