@gaganref/confect-cli 10.3.1-fork.2 → 10.3.1-fork.20

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.
Files changed (48) hide show
  1. package/dist/Bundler.mjs +22 -1
  2. package/dist/Bundler.mjs.map +1 -1
  3. package/dist/CodegenError.mjs +11 -2
  4. package/dist/CodegenError.mjs.map +1 -1
  5. package/dist/ConfectDirectory.mjs.map +1 -1
  6. package/dist/ConvexConfig.mjs.map +1 -1
  7. package/dist/ConvexDirectory.mjs.map +1 -1
  8. package/dist/DirectoryOptions.mjs.map +1 -1
  9. package/dist/EntryPoint.mjs.map +1 -1
  10. package/dist/Evaluation.mjs +39 -13
  11. package/dist/Evaluation.mjs.map +1 -1
  12. package/dist/EvaluationWorker.mjs +13 -1
  13. package/dist/EvaluationWorker.mjs.map +1 -1
  14. package/dist/FunctionModule.mjs +81 -13
  15. package/dist/FunctionModule.mjs.map +1 -1
  16. package/dist/FunctionPath.mjs.map +1 -1
  17. package/dist/FunctionPaths.mjs.map +1 -1
  18. package/dist/GenerationSnapshot.mjs.map +1 -1
  19. package/dist/GroupPaths.mjs.map +1 -1
  20. package/dist/ImplModulePath.mjs.map +1 -1
  21. package/dist/LeafModule.mjs +17 -17
  22. package/dist/LeafModule.mjs.map +1 -1
  23. package/dist/Remove.mjs.map +1 -1
  24. package/dist/Rollback.mjs.map +1 -1
  25. package/dist/SpecAssemblyNode.mjs.map +1 -1
  26. package/dist/SpecModulePath.mjs.map +1 -1
  27. package/dist/SyncState.mjs.map +1 -1
  28. package/dist/TableModule.mjs.map +1 -1
  29. package/dist/TableModulePath.mjs.map +1 -1
  30. package/dist/WatchBuild.mjs.map +1 -1
  31. package/dist/WatchTopology.mjs.map +1 -1
  32. package/dist/Watcher.mjs +57 -55
  33. package/dist/Watcher.mjs.map +1 -1
  34. package/dist/cliApp.mjs.map +1 -1
  35. package/dist/confect/codegen.mjs +75 -23
  36. package/dist/confect/codegen.mjs.map +1 -1
  37. package/dist/confect/declaration.mjs +4 -3
  38. package/dist/confect/declaration.mjs.map +1 -1
  39. package/dist/confect/dev.mjs +9 -4
  40. package/dist/confect/dev.mjs.map +1 -1
  41. package/dist/confect.mjs.map +1 -1
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/log.mjs.map +1 -1
  44. package/dist/templates.mjs +16 -12
  45. package/dist/templates.mjs.map +1 -1
  46. package/dist/utils.mjs +1 -1
  47. package/dist/utils.mjs.map +1 -1
  48. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"WatchBuild.mjs","names":["WatchGraph.affected","WatchGraph.make"],"sources":["../src/WatchBuild.ts"],"sourcesContent":["import * as Array from \"effect/Array\";\nimport * as Brand from \"effect/Brand\";\nimport type * as Crypto from \"effect/Crypto\";\nimport * as Data from \"effect/Data\";\nimport * as Effect from \"effect/Effect\";\nimport type * as FileSystem from \"effect/FileSystem\";\nimport * as Equal from \"effect/Equal\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as HashSet from \"effect/HashSet\";\nimport * as Match from \"effect/Match\";\nimport * as Hex from \"effect/encoding/Hex\";\nimport * as Option from \"effect/Option\";\nimport type { PlatformError } from \"effect/PlatformError\";\nimport * as Result from \"effect/Result\";\nimport type * as esbuild from \"esbuild\";\nimport * as WatchGraph from \"./WatchGraph\";\n\nexport type Failure = Data.TaggedEnum<{\n BuildFailed: {\n readonly errors: Array.NonEmptyReadonlyArray<esbuild.Message>;\n };\n InputCaptureFailed: { readonly file: string; readonly cause: PlatformError };\n OutputCaptureFailed: { readonly file: string; readonly cause: PlatformError };\n InvalidBuildResult: { readonly missing: \"metafile\" | \"outputFiles\" };\n}>;\nexport const Failure = Data.taggedEnum<Failure>();\nexport type Fingerprints = HashMap.HashMap<string, string>;\n\nexport interface Capture {\n readonly fingerprints: Fingerprints;\n readonly failures: HashMap.HashMap<string, Failure>;\n}\nexport const emptyCapture: Capture = {\n fingerprints: HashMap.empty(),\n failures: HashMap.empty(),\n};\n\nexport interface Snapshot {\n readonly fingerprints: Fingerprints;\n readonly graph: WatchGraph.WatchGraph;\n readonly outputHash: string;\n}\n\nexport type Outcome = Data.TaggedEnum<{\n Succeeded: {\n readonly snapshot: Snapshot;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n Failed: {\n readonly fingerprints: Fingerprints;\n readonly failures: Array.NonEmptyReadonlyArray<Failure>;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n}>;\nexport const Outcome = Data.taggedEnum<Outcome>();\n\nexport type Generation = number & Brand.Brand<\"WatchBuild.Generation\">;\nconst Generation = Brand.nominal<Generation>();\n\nexport type Barrier = number & Brand.Brand<\"WatchBuild.Barrier\">;\nconst Barrier = Brand.nominal<Barrier>();\n\nexport type RequestId = object & Brand.Brand<\"WatchBuild.RequestId\">;\nconst RequestId = Brand.nominal<RequestId>();\n\nexport const makeRequestId = (): RequestId => RequestId({});\n\nexport interface Completion {\n readonly generation: Generation;\n readonly outcome: Outcome;\n}\n\ntype Request = Data.TaggedEnum<{\n Idle: {};\n Pending: {};\n Joined: {};\n Completed: { readonly completion: Completion };\n}>;\nconst Request = Data.taggedEnum<Request>();\n\nexport interface Progress {\n readonly generation: Generation;\n readonly request: Request;\n readonly lastRequest: Option.Option<RequestId>;\n}\n\nexport const initialProgress: Progress = {\n generation: Generation(0),\n request: Request.Idle(),\n lastRequest: Option.none(),\n};\n\nexport const start = (progress: Progress): Progress => ({\n ...progress,\n generation: Generation(progress.generation + 1),\n});\n\nexport const captureBarrier = (progress: Progress): Barrier =>\n Barrier(progress.generation);\n\nexport const request = (progress: Progress, id: RequestId): Progress => ({\n ...progress,\n request:\n Option.isSome(progress.lastRequest) && progress.lastRequest.value === id\n ? Request.Joined()\n : Request.Pending(),\n lastRequest: Option.some(id),\n});\n\nexport const complete = (\n progress: Progress,\n completion: Completion,\n): Progress => ({\n ...progress,\n request: Request.$match(progress.request, {\n Idle: (idle) => idle,\n Pending: () => Request.Completed({ completion }),\n Joined: () => Request.Completed({ completion }),\n Completed: (completed) => completed,\n }),\n});\n\nexport const getCompletion = (progress: Progress): Option.Option<Completion> =>\n Request.$match(progress.request, {\n Idle: () => Option.none(),\n Pending: () => Option.none(),\n Joined: () => Option.none(),\n Completed: ({ completion }) => Option.some(completion),\n });\n\nexport const joinedWithoutCompletion = (progress: Progress): boolean =>\n Request.$is(\"Joined\")(progress.request);\n\nexport const endRequest = (progress: Progress): Progress => ({\n ...progress,\n request: Request.Idle(),\n});\n\nexport const isFresh = (barrier: Barrier, completion: Completion): boolean =>\n completion.generation > barrier;\n\nexport const verifyInputs = Effect.fn(\"WatchBuild.verifyInputs\")(function* (\n snapshot: Snapshot,\n fs: FileSystem.FileSystem,\n crypto: Crypto.Crypto,\n) {\n const matches = yield* Effect.forEach(\n snapshot.fingerprints,\n ([file, expected]) =>\n fs.readFile(file).pipe(\n Effect.flatMap((contents) => crypto.digest(\"SHA-256\", contents)),\n Effect.map((digest) => Hex.encode(digest) === expected),\n Effect.mapError((cause) => Failure.InputCaptureFailed({ file, cause })),\n ),\n { concurrency: 8 },\n );\n return Array.every(matches, (matchesInput) => matchesInput);\n});\n\nexport type State = Data.TaggedEnum<{\n Initial: {};\n Succeeded: {\n readonly snapshot: Snapshot;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n Failed: {\n readonly observation: Extract<Outcome, { readonly _tag: \"Failed\" }>;\n readonly lastSuccessful: Option.Option<Snapshot>;\n readonly discovered: HashSet.HashSet<string>;\n };\n}>;\nexport const State = Data.taggedEnum<State>();\n\nexport const lastSuccessful = (state: State): Option.Option<Snapshot> =>\n State.$match(state, {\n Initial: () => Option.none(),\n Succeeded: ({ snapshot }) => Option.some(snapshot),\n Failed: ({ lastSuccessful: snapshot }) => snapshot,\n });\n\nexport const observe = (previous: State, outcome: Outcome): State =>\n Outcome.$match(outcome, {\n Succeeded: ({ snapshot, warnings }) =>\n State.Succeeded({ snapshot, warnings }),\n Failed: (observation) =>\n State.Failed({\n observation,\n lastSuccessful: lastSuccessful(previous),\n discovered: State.$is(\"Initial\")(previous)\n ? HashSet.empty()\n : HashSet.union(\n State.$is(\"Failed\")(previous)\n ? previous.discovered\n : HashSet.empty(),\n HashSet.difference(\n HashSet.fromIterable(HashMap.keys(observation.fingerprints)),\n HashSet.fromIterable(HashMap.keys(fingerprints(previous))),\n ),\n ),\n }),\n });\n\nexport const fingerprints = (state: State): Fingerprints =>\n State.$match(state, {\n Initial: () => HashMap.empty(),\n Succeeded: ({ snapshot }) => snapshot.fingerprints,\n Failed: ({ observation }) => observation.fingerprints,\n });\n\nexport const outputHash = (state: State): Option.Option<string> =>\n State.$match(state, {\n Initial: () => Option.none(),\n Succeeded: ({ snapshot }) => Option.some(snapshot.outputHash),\n Failed: () => Option.none(),\n });\n\nexport type Change = Data.TaggedEnum<{\n Full: {};\n Affected: { readonly paths: HashSet.HashSet<string> };\n Recovered: { readonly paths: HashSet.HashSet<string> };\n}>;\nexport const Change = Data.taggedEnum<Change>();\n\nexport const diff = (\n previous: State,\n current: State,\n generatedDirectoryPrefix: string,\n): Change => {\n const previousFingerprints = fingerprints(previous);\n const currentFingerprints = fingerprints(current);\n const files = HashSet.union(\n HashSet.fromIterable(HashMap.keys(previousFingerprints)),\n HashSet.fromIterable(HashMap.keys(currentFingerprints)),\n );\n const changed = Array.fromIterable(files).filter(\n (file) =>\n !Equal.equals(\n HashMap.get(previousFingerprints, file),\n HashMap.get(currentFingerprints, file),\n ),\n );\n const sources = changed.filter(\n (file) => !file.startsWith(generatedDirectoryPrefix),\n );\n const recovered =\n State.$is(\"Failed\")(previous) && State.$is(\"Succeeded\")(current);\n const untrackedOutput = recovered\n ? Option.match(lastSuccessful(previous), {\n onNone: () => false,\n onSome: (baseline) =>\n Equal.equals(baseline.fingerprints, currentFingerprints) &&\n !Equal.equals(Option.some(baseline.outputHash), outputHash(current)),\n })\n : changed.length === 0 &&\n !Equal.equals(outputHash(previous), outputHash(current));\n if (\n State.$is(\"Initial\")(previous) ||\n (sources.some((file) => HashMap.has(previousFingerprints, file)) &&\n State.$is(\"Failed\")(current)) ||\n untrackedOutput\n )\n return Change.Full();\n\n const graph = Option.match(lastSuccessful(current), {\n onNone: () => HashMap.empty<string, HashSet.HashSet<string>>(),\n onSome: (snapshot) => snapshot.graph,\n });\n const previousGraph = Option.match(lastSuccessful(previous), {\n onNone: () => HashMap.empty<string, HashSet.HashSet<string>>(),\n onSome: (snapshot) => snapshot.graph,\n });\n const affectedSources =\n recovered && State.$is(\"Failed\")(previous)\n ? Array.fromIterable(\n HashSet.union(\n HashSet.fromIterable(sources),\n HashSet.filter(\n previous.discovered,\n (file) => !file.startsWith(generatedDirectoryPrefix),\n ),\n ),\n )\n : sources;\n const paths = HashSet.union(\n WatchGraph.affected(graph, affectedSources),\n WatchGraph.affected(previousGraph, affectedSources),\n );\n return recovered ? Change.Recovered({ paths }) : Change.Affected({ paths });\n};\n\nexport const parse = Effect.fn(\"WatchBuild.parse\")(function* (\n result: esbuild.BuildResult,\n capture: Capture,\n resolve: (file: string) => string,\n crypto: Crypto.Crypto,\n) {\n const failures = Array.fromIterable(HashMap.values(capture.failures));\n if (Array.isReadonlyArrayNonEmpty(result.errors))\n failures.push(Failure.BuildFailed({ errors: result.errors }));\n if (Array.isReadonlyArrayNonEmpty(failures))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures,\n warnings: result.warnings,\n });\n if (!result.metafile)\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [Failure.InvalidBuildResult({ missing: \"metafile\" })],\n warnings: result.warnings,\n });\n if (!result.outputFiles || !Array.isReadonlyArrayNonEmpty(result.outputFiles))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [Failure.InvalidBuildResult({ missing: \"outputFiles\" })],\n warnings: result.warnings,\n });\n const hashes = yield* Effect.forEach(result.outputFiles, (file) =>\n crypto.digest(\"SHA-256\", file.contents).pipe(\n Effect.map(Hex.encode),\n Effect.mapError((cause) =>\n Failure.OutputCaptureFailed({ file: file.path, cause }),\n ),\n ),\n ).pipe(Effect.result);\n if (Result.isFailure(hashes))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [hashes.failure],\n warnings: result.warnings,\n });\n return Outcome.Succeeded({\n snapshot: {\n fingerprints: capture.fingerprints,\n graph: WatchGraph.make(result.metafile, resolve),\n outputHash: hashes.success.join(\":\"),\n },\n warnings: result.warnings,\n });\n});\n\nexport const failureMessage = (failure: Failure): string =>\n Failure.$match(failure, {\n BuildFailed: ({ errors }) => errors.map((error) => error.text).join(\"\\n\"),\n InputCaptureFailed: ({ file, cause }) =>\n `Could not fingerprint input ${file}: ${cause.message}`,\n OutputCaptureFailed: ({ file, cause }) =>\n `Could not fingerprint output ${file}: ${cause.message}`,\n InvalidBuildResult: ({ missing }) => `esbuild completed without ${missing}`,\n });\n\nexport const messages = (outcome: Outcome): ReadonlyArray<esbuild.Message> =>\n Outcome.$match(outcome, {\n Succeeded: () => [],\n Failed: ({ failures }) =>\n failures.flatMap((failure) =>\n Match.value(failure).pipe(\n Match.tag(\"BuildFailed\", ({ errors }) => errors),\n Match.tag(\n \"InputCaptureFailed\",\n \"OutputCaptureFailed\",\n \"InvalidBuildResult\",\n (captureFailure) => [\n {\n id: \"confect-watch\",\n pluginName: \"confect\",\n text: failureMessage(captureFailure),\n location: null,\n notes: [],\n detail: captureFailure,\n },\n ],\n ),\n Match.exhaustive,\n ),\n ),\n });\n\nexport const diagnostics = (\n state: State,\n): {\n readonly errors: ReadonlyArray<esbuild.Message>;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n} =>\n State.$match(state, {\n Initial: () => ({ errors: [], warnings: [] }),\n Succeeded: ({ warnings }) => ({ errors: [], warnings }),\n Failed: ({ observation }) => ({\n errors: messages(observation),\n warnings: observation.warnings,\n }),\n });\n"],"mappings":"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"}
1
+ {"version":3,"file":"WatchBuild.mjs","names":["WatchGraph.affected","WatchGraph.make"],"sources":["../src/WatchBuild.ts"],"sourcesContent":["import * as Array from \"effect/Array\";\nimport * as Brand from \"effect/Brand\";\nimport type * as Crypto from \"effect/Crypto\";\nimport * as Data from \"effect/Data\";\nimport * as Effect from \"effect/Effect\";\nimport type * as FileSystem from \"effect/FileSystem\";\nimport * as Equal from \"effect/Equal\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as HashSet from \"effect/HashSet\";\nimport * as Match from \"effect/Match\";\nimport * as Hex from \"effect/encoding/Hex\";\nimport * as Option from \"effect/Option\";\nimport type { PlatformError } from \"effect/PlatformError\";\nimport * as Result from \"effect/Result\";\nimport type * as esbuild from \"esbuild\";\nimport * as WatchGraph from \"./WatchGraph.js\";\n\nexport type Failure = Data.TaggedEnum<{\n BuildFailed: {\n readonly errors: Array.NonEmptyReadonlyArray<esbuild.Message>;\n };\n InputCaptureFailed: { readonly file: string; readonly cause: PlatformError };\n OutputCaptureFailed: { readonly file: string; readonly cause: PlatformError };\n InvalidBuildResult: { readonly missing: \"metafile\" | \"outputFiles\" };\n}>;\nexport const Failure = Data.taggedEnum<Failure>();\nexport type Fingerprints = HashMap.HashMap<string, string>;\n\nexport interface Capture {\n readonly fingerprints: Fingerprints;\n readonly failures: HashMap.HashMap<string, Failure>;\n}\nexport const emptyCapture: Capture = {\n fingerprints: HashMap.empty(),\n failures: HashMap.empty(),\n};\n\nexport interface Snapshot {\n readonly fingerprints: Fingerprints;\n readonly graph: WatchGraph.WatchGraph;\n readonly outputHash: string;\n}\n\nexport type Outcome = Data.TaggedEnum<{\n Succeeded: {\n readonly snapshot: Snapshot;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n Failed: {\n readonly fingerprints: Fingerprints;\n readonly failures: Array.NonEmptyReadonlyArray<Failure>;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n}>;\nexport const Outcome = Data.taggedEnum<Outcome>();\n\nexport type Generation = number & Brand.Brand<\"WatchBuild.Generation\">;\nconst Generation = Brand.nominal<Generation>();\n\nexport type Barrier = number & Brand.Brand<\"WatchBuild.Barrier\">;\nconst Barrier = Brand.nominal<Barrier>();\n\nexport type RequestId = object & Brand.Brand<\"WatchBuild.RequestId\">;\nconst RequestId = Brand.nominal<RequestId>();\n\nexport const makeRequestId = (): RequestId => RequestId({});\n\nexport interface Completion {\n readonly generation: Generation;\n readonly outcome: Outcome;\n}\n\ntype Request = Data.TaggedEnum<{\n Idle: {};\n Pending: {};\n Joined: {};\n Completed: { readonly completion: Completion };\n}>;\nconst Request = Data.taggedEnum<Request>();\n\nexport interface Progress {\n readonly generation: Generation;\n readonly request: Request;\n readonly lastRequest: Option.Option<RequestId>;\n}\n\nexport const initialProgress: Progress = {\n generation: Generation(0),\n request: Request.Idle(),\n lastRequest: Option.none(),\n};\n\nexport const start = (progress: Progress): Progress => ({\n ...progress,\n generation: Generation(progress.generation + 1),\n});\n\nexport const captureBarrier = (progress: Progress): Barrier =>\n Barrier(progress.generation);\n\nexport const request = (progress: Progress, id: RequestId): Progress => ({\n ...progress,\n request:\n Option.isSome(progress.lastRequest) && progress.lastRequest.value === id\n ? Request.Joined()\n : Request.Pending(),\n lastRequest: Option.some(id),\n});\n\nexport const complete = (\n progress: Progress,\n completion: Completion,\n): Progress => ({\n ...progress,\n request: Request.$match(progress.request, {\n Idle: (idle) => idle,\n Pending: () => Request.Completed({ completion }),\n Joined: () => Request.Completed({ completion }),\n Completed: (completed) => completed,\n }),\n});\n\nexport const getCompletion = (progress: Progress): Option.Option<Completion> =>\n Request.$match(progress.request, {\n Idle: () => Option.none(),\n Pending: () => Option.none(),\n Joined: () => Option.none(),\n Completed: ({ completion }) => Option.some(completion),\n });\n\nexport const joinedWithoutCompletion = (progress: Progress): boolean =>\n Request.$is(\"Joined\")(progress.request);\n\nexport const endRequest = (progress: Progress): Progress => ({\n ...progress,\n request: Request.Idle(),\n});\n\nexport const isFresh = (barrier: Barrier, completion: Completion): boolean =>\n completion.generation > barrier;\n\nexport const verifyInputs = Effect.fn(\"WatchBuild.verifyInputs\")(function* (\n snapshot: Snapshot,\n fs: FileSystem.FileSystem,\n crypto: Crypto.Crypto,\n) {\n const matches = yield* Effect.forEach(\n snapshot.fingerprints,\n ([file, expected]) =>\n fs.readFile(file).pipe(\n Effect.flatMap((contents) => crypto.digest(\"SHA-256\", contents)),\n Effect.map((digest) => Hex.encode(digest) === expected),\n Effect.mapError((cause) => Failure.InputCaptureFailed({ file, cause })),\n ),\n { concurrency: 8 },\n );\n return Array.every(matches, (matchesInput) => matchesInput);\n});\n\nexport type State = Data.TaggedEnum<{\n Initial: {};\n Succeeded: {\n readonly snapshot: Snapshot;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n };\n Failed: {\n readonly observation: Extract<Outcome, { readonly _tag: \"Failed\" }>;\n readonly lastSuccessful: Option.Option<Snapshot>;\n readonly discovered: HashSet.HashSet<string>;\n };\n}>;\nexport const State = Data.taggedEnum<State>();\n\nexport const lastSuccessful = (state: State): Option.Option<Snapshot> =>\n State.$match(state, {\n Initial: () => Option.none(),\n Succeeded: ({ snapshot }) => Option.some(snapshot),\n Failed: ({ lastSuccessful: snapshot }) => snapshot,\n });\n\nexport const observe = (previous: State, outcome: Outcome): State =>\n Outcome.$match(outcome, {\n Succeeded: ({ snapshot, warnings }) =>\n State.Succeeded({ snapshot, warnings }),\n Failed: (observation) =>\n State.Failed({\n observation,\n lastSuccessful: lastSuccessful(previous),\n discovered: State.$is(\"Initial\")(previous)\n ? HashSet.empty()\n : HashSet.union(\n State.$is(\"Failed\")(previous)\n ? previous.discovered\n : HashSet.empty(),\n HashSet.difference(\n HashSet.fromIterable(HashMap.keys(observation.fingerprints)),\n HashSet.fromIterable(HashMap.keys(fingerprints(previous))),\n ),\n ),\n }),\n });\n\nexport const fingerprints = (state: State): Fingerprints =>\n State.$match(state, {\n Initial: () => HashMap.empty(),\n Succeeded: ({ snapshot }) => snapshot.fingerprints,\n Failed: ({ observation }) => observation.fingerprints,\n });\n\nexport const outputHash = (state: State): Option.Option<string> =>\n State.$match(state, {\n Initial: () => Option.none(),\n Succeeded: ({ snapshot }) => Option.some(snapshot.outputHash),\n Failed: () => Option.none(),\n });\n\nexport type Change = Data.TaggedEnum<{\n Full: {};\n Affected: { readonly paths: HashSet.HashSet<string> };\n Recovered: { readonly paths: HashSet.HashSet<string> };\n}>;\nexport const Change = Data.taggedEnum<Change>();\n\nexport const diff = (\n previous: State,\n current: State,\n generatedDirectoryPrefix: string,\n): Change => {\n const previousFingerprints = fingerprints(previous);\n const currentFingerprints = fingerprints(current);\n const files = HashSet.union(\n HashSet.fromIterable(HashMap.keys(previousFingerprints)),\n HashSet.fromIterable(HashMap.keys(currentFingerprints)),\n );\n const changed = Array.fromIterable(files).filter(\n (file) =>\n !Equal.equals(\n HashMap.get(previousFingerprints, file),\n HashMap.get(currentFingerprints, file),\n ),\n );\n const sources = changed.filter(\n (file) => !file.startsWith(generatedDirectoryPrefix),\n );\n const recovered =\n State.$is(\"Failed\")(previous) && State.$is(\"Succeeded\")(current);\n const untrackedOutput = recovered\n ? Option.match(lastSuccessful(previous), {\n onNone: () => false,\n onSome: (baseline) =>\n Equal.equals(baseline.fingerprints, currentFingerprints) &&\n !Equal.equals(Option.some(baseline.outputHash), outputHash(current)),\n })\n : changed.length === 0 &&\n !Equal.equals(outputHash(previous), outputHash(current));\n if (\n State.$is(\"Initial\")(previous) ||\n (sources.some((file) => HashMap.has(previousFingerprints, file)) &&\n State.$is(\"Failed\")(current)) ||\n untrackedOutput\n )\n return Change.Full();\n\n const graph = Option.match(lastSuccessful(current), {\n onNone: () => HashMap.empty<string, HashSet.HashSet<string>>(),\n onSome: (snapshot) => snapshot.graph,\n });\n const previousGraph = Option.match(lastSuccessful(previous), {\n onNone: () => HashMap.empty<string, HashSet.HashSet<string>>(),\n onSome: (snapshot) => snapshot.graph,\n });\n const affectedSources =\n recovered && State.$is(\"Failed\")(previous)\n ? Array.fromIterable(\n HashSet.union(\n HashSet.fromIterable(sources),\n HashSet.filter(\n previous.discovered,\n (file) => !file.startsWith(generatedDirectoryPrefix),\n ),\n ),\n )\n : sources;\n const paths = HashSet.union(\n WatchGraph.affected(graph, affectedSources),\n WatchGraph.affected(previousGraph, affectedSources),\n );\n return recovered ? Change.Recovered({ paths }) : Change.Affected({ paths });\n};\n\nexport const parse = Effect.fn(\"WatchBuild.parse\")(function* (\n result: esbuild.BuildResult,\n capture: Capture,\n resolve: (file: string) => string,\n crypto: Crypto.Crypto,\n) {\n const failures = Array.fromIterable(HashMap.values(capture.failures));\n if (Array.isReadonlyArrayNonEmpty(result.errors))\n failures.push(Failure.BuildFailed({ errors: result.errors }));\n if (Array.isReadonlyArrayNonEmpty(failures))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures,\n warnings: result.warnings,\n });\n if (!result.metafile)\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [Failure.InvalidBuildResult({ missing: \"metafile\" })],\n warnings: result.warnings,\n });\n if (!result.outputFiles || !Array.isReadonlyArrayNonEmpty(result.outputFiles))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [Failure.InvalidBuildResult({ missing: \"outputFiles\" })],\n warnings: result.warnings,\n });\n const hashes = yield* Effect.forEach(result.outputFiles, (file) =>\n crypto.digest(\"SHA-256\", file.contents).pipe(\n Effect.map(Hex.encode),\n Effect.mapError((cause) =>\n Failure.OutputCaptureFailed({ file: file.path, cause }),\n ),\n ),\n ).pipe(Effect.result);\n if (Result.isFailure(hashes))\n return Outcome.Failed({\n fingerprints: capture.fingerprints,\n failures: [hashes.failure],\n warnings: result.warnings,\n });\n return Outcome.Succeeded({\n snapshot: {\n fingerprints: capture.fingerprints,\n graph: WatchGraph.make(result.metafile, resolve),\n outputHash: hashes.success.join(\":\"),\n },\n warnings: result.warnings,\n });\n});\n\nexport const failureMessage = (failure: Failure): string =>\n Failure.$match(failure, {\n BuildFailed: ({ errors }) => errors.map((error) => error.text).join(\"\\n\"),\n InputCaptureFailed: ({ file, cause }) =>\n `Could not fingerprint input ${file}: ${cause.message}`,\n OutputCaptureFailed: ({ file, cause }) =>\n `Could not fingerprint output ${file}: ${cause.message}`,\n InvalidBuildResult: ({ missing }) => `esbuild completed without ${missing}`,\n });\n\nexport const messages = (outcome: Outcome): ReadonlyArray<esbuild.Message> =>\n Outcome.$match(outcome, {\n Succeeded: () => [],\n Failed: ({ failures }) =>\n failures.flatMap((failure) =>\n Match.value(failure).pipe(\n Match.tag(\"BuildFailed\", ({ errors }) => errors),\n Match.tag(\n \"InputCaptureFailed\",\n \"OutputCaptureFailed\",\n \"InvalidBuildResult\",\n (captureFailure) => [\n {\n id: \"confect-watch\",\n pluginName: \"confect\",\n text: failureMessage(captureFailure),\n location: null,\n notes: [],\n detail: captureFailure,\n },\n ],\n ),\n Match.exhaustive,\n ),\n ),\n });\n\nexport const diagnostics = (\n state: State,\n): {\n readonly errors: ReadonlyArray<esbuild.Message>;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n} =>\n State.$match(state, {\n Initial: () => ({ errors: [], warnings: [] }),\n Succeeded: ({ warnings }) => ({ errors: [], warnings }),\n Failed: ({ observation }) => ({\n errors: messages(observation),\n warnings: observation.warnings,\n }),\n });\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WatchTopology.mjs","names":["SyncState.full","SyncState.add","SyncState.empty"],"sources":["../src/WatchTopology.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\nimport * as Ref from \"effect/Ref\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport type { Kind } from \"./EntryPoint\";\nimport * as SyncState from \"./SyncState\";\n\ntype State = Data.TaggedEnum<{\n Reconciling: { readonly revision: number };\n Observing: {\n readonly revision: number;\n readonly initial: Deferred.Deferred<void>;\n };\n}>;\nconst State = Data.taggedEnum<State>();\n\ntype Decision = Data.TaggedEnum<{\n Take: { readonly pending: SyncState.Pending };\n Wait: { readonly ready: Effect.Effect<void> };\n}>;\nconst Decision = Data.taggedEnum<Decision>();\n\nexport const make = Effect.fn(\"WatchTopology.make\")(function* (\n pending: Ref.Ref<SyncState.Pending>,\n) {\n const state = yield* Ref.make<State>(State.Reconciling({ revision: 0 }));\n const changed = yield* Ref.make(yield* Deferred.make<void>());\n const lock = yield* Semaphore.make(1);\n const notify = Effect.gen(function* () {\n const previous = yield* Ref.getAndSet(\n changed,\n yield* Deferred.make<void>(),\n );\n yield* Deferred.succeed(previous, undefined);\n });\n\n const invalidate = Effect.fn(\"WatchTopology.invalidate\")(\n function* (update: (pending: SyncState.Pending) => SyncState.Pending) {\n yield* Ref.update(state, ({ revision }) =>\n State.Reconciling({ revision: revision + 1 }),\n );\n yield* Ref.update(pending, update);\n yield* notify;\n },\n (effect) => lock.withPermit(effect),\n );\n\n return {\n revision: Ref.get(state).pipe(Effect.map((current) => current.revision)),\n invalidate: invalidate(SyncState.full),\n invalidateEntry: (entry: Kind) =>\n invalidate((current) => SyncState.add(current, [entry])),\n reconcile: Effect.fn(\"WatchTopology.reconcile\")(\n function* (revision: number, initial: Deferred.Deferred<void>) {\n const current = yield* Ref.get(state);\n if (current.revision !== revision) return;\n yield* Ref.set(state, State.Observing({ revision, initial }));\n yield* notify;\n },\n (effect) => lock.withPermit(effect),\n ),\n takePending: lock\n .withPermit(\n Effect.gen(function* () {\n const current = yield* Ref.get(state);\n const notification = yield* Ref.get(changed);\n return yield* State.$match(current, {\n Reconciling: () =>\n Effect.succeed(\n Decision.Wait({ ready: Deferred.await(notification) }),\n ),\n Observing: ({ initial }) =>\n Effect.gen(function* () {\n if (yield* Deferred.isDone(initial))\n return Decision.Take({\n pending: yield* Ref.getAndSet(pending, SyncState.empty),\n });\n return Decision.Wait({\n ready: Effect.raceFirst(\n Deferred.await(notification),\n Deferred.await(initial),\n ),\n });\n }),\n });\n }),\n )\n .pipe(\n Effect.flatMap(\n Decision.$match({\n Take: ({ pending: taken }) => Effect.succeedSome(taken),\n Wait: ({ ready }) =>\n ready.pipe(Effect.as(Option.none<SyncState.Pending>())),\n }),\n ),\n Effect.repeat({ until: Option.isSome<SyncState.Pending> }),\n Effect.map((result) => result.value),\n ),\n };\n});\n\nexport type WatchTopology = Effect.Success<ReturnType<typeof make>>;\n"],"mappings":";;;;;;;;AAgBA,MAAM,QAAQ,KAAK,WAAkB;AAMrC,MAAM,WAAW,KAAK,WAAqB;AAE3C,MAAa,OAAO,OAAO,GAAG,oBAAoB,CAAC,CAAC,WAClD,SACA;CACA,MAAM,QAAQ,OAAO,IAAI,KAAY,MAAM,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;CACvE,MAAM,UAAU,OAAO,IAAI,KAAK,OAAO,SAAS,KAAW,CAAC;CAC5D,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,SAAS,OAAO,IAAI,aAAa;EACrC,MAAM,WAAW,OAAO,IAAI,UAC1B,SACA,OAAO,SAAS,KAAW,CAC7B;EACA,OAAO,SAAS,QAAQ,UAAU,KAAA,CAAS;CAC7C,CAAC;CAED,MAAM,aAAa,OAAO,GAAG,0BAA0B,CAAC,CACtD,WAAW,QAA2D;EACpE,OAAO,IAAI,OAAO,QAAQ,EAAE,eAC1B,MAAM,YAAY,EAAE,UAAU,WAAW,EAAE,CAAC,CAC9C;EACA,OAAO,IAAI,OAAO,SAAS,MAAM;EACjC,OAAO;CACT,IACC,WAAW,KAAK,WAAW,MAAM,CACpC;CAEA,OAAO;EACL,UAAU,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,QAAQ,CAAC;EACvE,YAAY,WAAWA,IAAc;EACrC,kBAAkB,UAChB,YAAY,YAAYC,IAAc,SAAS,CAAC,KAAK,CAAC,CAAC;EACzD,WAAW,OAAO,GAAG,yBAAyB,CAAC,CAC7C,WAAW,UAAkB,SAAkC;GAE7D,KAAI,OADmB,IAAI,IAAI,KAAK,EAAA,CACxB,aAAa,UAAU;GACnC,OAAO,IAAI,IAAI,OAAO,MAAM,UAAU;IAAE;IAAU;GAAQ,CAAC,CAAC;GAC5D,OAAO;EACT,IACC,WAAW,KAAK,WAAW,MAAM,CACpC;EACA,aAAa,KACV,WACC,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,KAAK;GACpC,MAAM,eAAe,OAAO,IAAI,IAAI,OAAO;GAC3C,OAAO,OAAO,MAAM,OAAO,SAAS;IAClC,mBACE,OAAO,QACL,SAAS,KAAK,EAAE,OAAO,SAAS,MAAM,YAAY,EAAE,CAAC,CACvD;IACF,YAAY,EAAE,cACZ,OAAO,IAAI,aAAa;KACtB,IAAI,OAAO,SAAS,OAAO,OAAO,GAChC,OAAO,SAAS,KAAK,EACnB,SAAS,OAAO,IAAI,UAAU,SAASC,KAAe,EACxD,CAAC;KACH,OAAO,SAAS,KAAK,EACnB,OAAO,OAAO,UACZ,SAAS,MAAM,YAAY,GAC3B,SAAS,MAAM,OAAO,CACxB,EACF,CAAC;IACH,CAAC;GACL,CAAC;EACH,CAAC,CACH,CAAC,CACA,KACC,OAAO,QACL,SAAS,OAAO;GACd,OAAO,EAAE,SAAS,YAAY,OAAO,YAAY,KAAK;GACtD,OAAO,EAAE,YACP,MAAM,KAAK,OAAO,GAAG,OAAO,KAAwB,CAAC,CAAC;EAC1D,CAAC,CACH,GACA,OAAO,OAAO,EAAE,OAAO,OAAO,OAA0B,CAAC,GACzD,OAAO,KAAK,WAAW,OAAO,KAAK,CACrC;CACJ;AACF,CAAC"}
1
+ {"version":3,"file":"WatchTopology.mjs","names":["SyncState.full","SyncState.add","SyncState.empty"],"sources":["../src/WatchTopology.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\nimport * as Deferred from \"effect/Deferred\";\nimport * as Effect from \"effect/Effect\";\nimport * as Option from \"effect/Option\";\nimport * as Ref from \"effect/Ref\";\nimport * as Semaphore from \"effect/Semaphore\";\nimport type { Kind } from \"./EntryPoint.js\";\nimport * as SyncState from \"./SyncState.js\";\n\ntype State = Data.TaggedEnum<{\n Reconciling: { readonly revision: number };\n Observing: {\n readonly revision: number;\n readonly initial: Deferred.Deferred<void>;\n };\n}>;\nconst State = Data.taggedEnum<State>();\n\ntype Decision = Data.TaggedEnum<{\n Take: { readonly pending: SyncState.Pending };\n Wait: { readonly ready: Effect.Effect<void> };\n}>;\nconst Decision = Data.taggedEnum<Decision>();\n\nexport const make = Effect.fn(\"WatchTopology.make\")(function* (\n pending: Ref.Ref<SyncState.Pending>,\n) {\n const state = yield* Ref.make<State>(State.Reconciling({ revision: 0 }));\n const changed = yield* Ref.make(yield* Deferred.make<void>());\n const lock = yield* Semaphore.make(1);\n const notify = Effect.gen(function* () {\n const previous = yield* Ref.getAndSet(\n changed,\n yield* Deferred.make<void>(),\n );\n yield* Deferred.succeed(previous, undefined);\n });\n\n const invalidate = Effect.fn(\"WatchTopology.invalidate\")(\n function* (update: (pending: SyncState.Pending) => SyncState.Pending) {\n yield* Ref.update(state, ({ revision }) =>\n State.Reconciling({ revision: revision + 1 }),\n );\n yield* Ref.update(pending, update);\n yield* notify;\n },\n (effect) => lock.withPermit(effect),\n );\n\n return {\n revision: Ref.get(state).pipe(Effect.map((current) => current.revision)),\n invalidate: invalidate(SyncState.full),\n invalidateEntry: (entry: Kind) =>\n invalidate((current) => SyncState.add(current, [entry])),\n reconcile: Effect.fn(\"WatchTopology.reconcile\")(\n function* (revision: number, initial: Deferred.Deferred<void>) {\n const current = yield* Ref.get(state);\n if (current.revision !== revision) return;\n yield* Ref.set(state, State.Observing({ revision, initial }));\n yield* notify;\n },\n (effect) => lock.withPermit(effect),\n ),\n takePending: lock\n .withPermit(\n Effect.gen(function* () {\n const current = yield* Ref.get(state);\n const notification = yield* Ref.get(changed);\n return yield* State.$match(current, {\n Reconciling: () =>\n Effect.succeed(\n Decision.Wait({ ready: Deferred.await(notification) }),\n ),\n Observing: ({ initial }) =>\n Effect.gen(function* () {\n if (yield* Deferred.isDone(initial))\n return Decision.Take({\n pending: yield* Ref.getAndSet(pending, SyncState.empty),\n });\n return Decision.Wait({\n ready: Effect.raceFirst(\n Deferred.await(notification),\n Deferred.await(initial),\n ),\n });\n }),\n });\n }),\n )\n .pipe(\n Effect.flatMap(\n Decision.$match({\n Take: ({ pending: taken }) => Effect.succeedSome(taken),\n Wait: ({ ready }) =>\n ready.pipe(Effect.as(Option.none<SyncState.Pending>())),\n }),\n ),\n Effect.repeat({ until: Option.isSome<SyncState.Pending> }),\n Effect.map((result) => result.value),\n ),\n };\n});\n\nexport type WatchTopology = Effect.Success<ReturnType<typeof make>>;\n"],"mappings":";;;;;;;;AAgBA,MAAM,QAAQ,KAAK,WAAkB;AAMrC,MAAM,WAAW,KAAK,WAAqB;AAE3C,MAAa,OAAO,OAAO,GAAG,oBAAoB,CAAC,CAAC,WAClD,SACA;CACA,MAAM,QAAQ,OAAO,IAAI,KAAY,MAAM,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;CACvE,MAAM,UAAU,OAAO,IAAI,KAAK,OAAO,SAAS,KAAW,CAAC;CAC5D,MAAM,OAAO,OAAO,UAAU,KAAK,CAAC;CACpC,MAAM,SAAS,OAAO,IAAI,aAAa;EACrC,MAAM,WAAW,OAAO,IAAI,UAC1B,SACA,OAAO,SAAS,KAAW,CAC7B;EACA,OAAO,SAAS,QAAQ,UAAU,KAAA,CAAS;CAC7C,CAAC;CAED,MAAM,aAAa,OAAO,GAAG,0BAA0B,CAAC,CACtD,WAAW,QAA2D;EACpE,OAAO,IAAI,OAAO,QAAQ,EAAE,eAC1B,MAAM,YAAY,EAAE,UAAU,WAAW,EAAE,CAAC,CAC9C;EACA,OAAO,IAAI,OAAO,SAAS,MAAM;EACjC,OAAO;CACT,IACC,WAAW,KAAK,WAAW,MAAM,CACpC;CAEA,OAAO;EACL,UAAU,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,QAAQ,CAAC;EACvE,YAAY,WAAWA,IAAc;EACrC,kBAAkB,UAChB,YAAY,YAAYC,IAAc,SAAS,CAAC,KAAK,CAAC,CAAC;EACzD,WAAW,OAAO,GAAG,yBAAyB,CAAC,CAC7C,WAAW,UAAkB,SAAkC;GAE7D,KAAI,OADmB,IAAI,IAAI,KAAK,EAAA,CACxB,aAAa,UAAU;GACnC,OAAO,IAAI,IAAI,OAAO,MAAM,UAAU;IAAE;IAAU;GAAQ,CAAC,CAAC;GAC5D,OAAO;EACT,IACC,WAAW,KAAK,WAAW,MAAM,CACpC;EACA,aAAa,KACV,WACC,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,KAAK;GACpC,MAAM,eAAe,OAAO,IAAI,IAAI,OAAO;GAC3C,OAAO,OAAO,MAAM,OAAO,SAAS;IAClC,mBACE,OAAO,QACL,SAAS,KAAK,EAAE,OAAO,SAAS,MAAM,YAAY,EAAE,CAAC,CACvD;IACF,YAAY,EAAE,cACZ,OAAO,IAAI,aAAa;KACtB,IAAI,OAAO,SAAS,OAAO,OAAO,GAChC,OAAO,SAAS,KAAK,EACnB,SAAS,OAAO,IAAI,UAAU,SAASC,KAAe,EACxD,CAAC;KACH,OAAO,SAAS,KAAK,EACnB,OAAO,OAAO,UACZ,SAAS,MAAM,YAAY,GAC3B,SAAS,MAAM,OAAO,CACxB,EACF,CAAC;IACH,CAAC;GACL,CAAC;EACH,CAAC,CACH,CAAC,CACA,KACC,OAAO,QACL,SAAS,OAAO;GACd,OAAO,EAAE,SAAS,YAAY,OAAO,YAAY,KAAK;GACtD,OAAO,EAAE,YACP,MAAM,KAAK,OAAO,GAAG,OAAO,KAAwB,CAAC,CAAC;EAC1D,CAAC,CACH,GACA,OAAO,OAAO,EAAE,OAAO,OAAO,OAA0B,CAAC,GACzD,OAAO,KAAK,WAAW,OAAO,KAAK,CACrC;CACJ;AACF,CAAC"}
package/dist/Watcher.mjs CHANGED
@@ -18,6 +18,7 @@ import * as HashSet from "effect/HashSet";
18
18
  import * as Match from "effect/Match";
19
19
  import * as Option from "effect/Option";
20
20
  import { externalPlugin, loadTsConfig, tsconfigPathsToRegExp } from "bundle-require";
21
+ import * as Context from "effect/Context";
21
22
  import * as HashMap from "effect/HashMap";
22
23
  import * as Ref from "effect/Ref";
23
24
  import * as Scope from "effect/Scope";
@@ -26,8 +27,8 @@ import * as esbuild from "esbuild";
26
27
  import * as Order from "effect/Order";
27
28
  import * as Data from "effect/Data";
28
29
  import * as Schedule from "effect/Schedule";
29
- import * as Clock from "effect/Clock";
30
30
  import * as Duration from "effect/Duration";
31
+ import * as Clock from "effect/Clock";
31
32
  import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
32
33
  import * as Crypto from "effect/Crypto";
33
34
  import * as Hex from "effect/encoding/Hex";
@@ -37,7 +38,7 @@ import * as Queue from "effect/Queue";
37
38
  import * as Semaphore from "effect/Semaphore";
38
39
  import * as Stream from "effect/Stream";
39
40
  //#region src/Watcher.ts
40
- const COALESCE_QUIESCENCE = Duration.millis(300);
41
+ const CoalesceQuiescence = Context.Reference("@confect/cli/Watcher/CoalesceQuiescence", { defaultValue: () => Duration.millis(50) });
41
42
  const COALESCE_MAX_WAIT = Duration.seconds(5);
42
43
  const WatcherLifecycle = Data.taggedEnum();
43
44
  const RefreshOutcome = Data.taggedEnum();
@@ -61,6 +62,7 @@ var OperationError = class extends Schema.TaggedError()("WatcherOperationError",
61
62
  const ReportedBuildFailure = Schema.Struct({ errors: Schema.NonEmptyArray(Schema.Struct({ text: Schema.String })) });
62
63
  const parseFailure = Schema.decodeUnknownOption(ReportedBuildFailure);
63
64
  const make = Effect.fnUntraced(function* () {
65
+ const quiescence = yield* CoalesceQuiescence;
64
66
  const signal = yield* Queue.sliding(1);
65
67
  const pendingRef = yield* Ref.make(empty);
66
68
  const restartQueue = yield* Queue.sliding(1);
@@ -88,7 +90,7 @@ const make = Effect.fnUntraced(function* () {
88
90
  duringRestore: Effect.flatten(Ref.get(duringRestoreRef)),
89
91
  discardRestoreEchoes: refresh(state).pipe(Effect.ignore, Effect.andThen(Ref.set(pendingRef, empty))),
90
92
  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))),
93
+ next: Queue.take(signal).pipe(Effect.andThen(drainUntilQuiescent(signal, quiescence, COALESCE_MAX_WAIT)), Effect.andThen(state.topology.takePending), Effect.onInterrupt(() => Queue.offer(signal, void 0))),
92
94
  pending: Ref.get(pendingRef),
93
95
  requestRetry: Ref.update(pendingRef, full).pipe(Effect.andThen(Queue.offer(signal, void 0)), Effect.asVoid),
94
96
  diagnostics: Ref.get(state.observation).pipe(Effect.map(diagnostics))
@@ -98,7 +100,8 @@ const drainUntilQuiescent = Effect.fnUntraced(function* (signal, quiescence, max
98
100
  const start = yield* Clock.currentTimeMillis;
99
101
  const maxMillis = Duration.toMillis(maxWait);
100
102
  const loop = Effect.gen(function* () {
101
- yield* Effect.sleep(quiescence);
103
+ const elapsed = (yield* Clock.currentTimeMillis) - start;
104
+ yield* Effect.sleep(Duration.millis(Math.min(Duration.toMillis(quiescence), Math.max(0, maxMillis - elapsed))));
102
105
  if ((yield* Queue.clear(signal)).length === 0) return;
103
106
  if ((yield* Clock.currentTimeMillis) - start < maxMillis) yield* loop;
104
107
  });
@@ -193,6 +196,7 @@ const entryPointsWatcher = Effect.fnUntraced(function* (signal, pendingRef, rest
193
196
  Empty: () => completedInitial,
194
197
  Active: ({ initial: activeInitial }) => Effect.succeed(activeInitial)
195
198
  });
199
+ yield* refreshCurrent(current).pipe(Effect.catchTag("WatcherOperationError", () => Ref.update(pendingRef, full)));
196
200
  yield* watcher.topology.reconcile(revision, initial);
197
201
  return;
198
202
  }
@@ -263,59 +267,57 @@ const entryPointsWatcher = Effect.fnUntraced(function* (signal, pendingRef, rest
263
267
  yield* sync;
264
268
  return yield* Effect.forever(Queue.take(restartQueue).pipe(Effect.andThen(sync)));
265
269
  }, Effect.provide(NodeCrypto.layer));
266
- const refresh = Effect.fnUntraced(function* (watcher) {
267
- return yield* watcher.lock.withPermit(Effect.gen(function* () {
268
- const current = yield* Ref.get(watcher.lifecycle);
269
- return yield* WatcherLifecycle.$match(current, {
270
- Empty: () => Effect.succeed(RefreshOutcome.Empty()),
271
- Uninitialized: () => Effect.fail(new OperationError({
272
- operation: "refresh",
273
- cause: "The dependency watcher is not initialized"
274
- })),
275
- Active: ({ context, identifyRequest, progress, verifyInputs }) => Effect.gen(function* () {
276
- const runSync = Effect.runSyncWith(yield* Effect.context());
277
- const barrier = captureBarrier(yield* Ref.get(progress));
278
- const completed = yield* Effect.gen(function* () {
279
- const built = yield* Effect.tryPromise({
280
- try: () => {
281
- const promise = context.rebuild();
282
- runSync(Ref.update(progress, (currentProgress) => request(currentProgress, identifyRequest(promise))));
283
- return promise;
284
- },
285
- catch: (cause) => new OperationError({
286
- operation: "rebuild",
287
- cause
288
- })
289
- }).pipe(Effect.result);
290
- const currentProgress = yield* Ref.get(progress);
291
- const completed = getCompletion(currentProgress);
292
- if (Result.isFailure(built)) {
293
- const rejected = parseFailure(built.failure.cause);
294
- if (Option.isNone(rejected)) return yield* built.failure;
295
- if (joinedWithoutCompletion(currentProgress)) return Option.none();
296
- if (Option.isNone(completed) || !Outcome.$is("Failed")(completed.value.outcome)) return yield* new OperationError({
297
- operation: "rebuild",
298
- cause: rejected.value.errors
299
- });
300
- }
270
+ const refreshCurrent = Effect.fnUntraced(function* (current) {
271
+ return yield* WatcherLifecycle.$match(current, {
272
+ Empty: () => Effect.succeed(RefreshOutcome.Empty()),
273
+ Uninitialized: () => Effect.fail(new OperationError({
274
+ operation: "refresh",
275
+ cause: "The dependency watcher is not initialized"
276
+ })),
277
+ Active: ({ context, identifyRequest, progress, verifyInputs }) => Effect.gen(function* () {
278
+ const runSync = Effect.runSyncWith(yield* Effect.context());
279
+ const barrier = captureBarrier(yield* Ref.get(progress));
280
+ const completed = yield* Effect.gen(function* () {
281
+ const built = yield* Effect.tryPromise({
282
+ try: () => {
283
+ const promise = context.rebuild();
284
+ runSync(Ref.update(progress, (currentProgress) => request(currentProgress, identifyRequest(promise))));
285
+ return promise;
286
+ },
287
+ catch: (cause) => new OperationError({
288
+ operation: "rebuild",
289
+ cause
290
+ })
291
+ }).pipe(Effect.result);
292
+ const currentProgress = yield* Ref.get(progress);
293
+ const completed = getCompletion(currentProgress);
294
+ if (Result.isFailure(built)) {
295
+ const rejected = parseFailure(built.failure.cause);
296
+ if (Option.isNone(rejected)) return yield* built.failure;
301
297
  if (joinedWithoutCompletion(currentProgress)) return Option.none();
302
- const observed = yield* Effect.fromOption(completed).pipe(Effect.mapError(() => new OperationError({
298
+ if (Option.isNone(completed) || !Outcome.$is("Failed")(completed.value.outcome)) return yield* new OperationError({
303
299
  operation: "rebuild",
304
- cause: "esbuild completed without a build observation"
305
- })));
306
- if (isFresh(barrier, observed) && Outcome.$is("Succeeded")(observed.outcome)) {
307
- if (!(yield* verifyInputs(observed.outcome.snapshot).pipe(Effect.mapError(({ cause }) => new OperationError({
308
- operation: "refresh",
309
- cause
310
- }))))) return Option.none();
311
- }
312
- return Option.some(observed);
313
- }).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)));
314
- return RefreshOutcome.Observed({ outcome: completed.outcome });
315
- })
316
- });
317
- }));
300
+ cause: rejected.value.errors
301
+ });
302
+ }
303
+ if (joinedWithoutCompletion(currentProgress)) return Option.none();
304
+ const observed = yield* Effect.fromOption(completed).pipe(Effect.mapError(() => new OperationError({
305
+ operation: "rebuild",
306
+ cause: "esbuild completed without a build observation"
307
+ })));
308
+ if (isFresh(barrier, observed) && Outcome.$is("Succeeded")(observed.outcome)) {
309
+ if (!(yield* verifyInputs(observed.outcome.snapshot).pipe(Effect.mapError(({ cause }) => new OperationError({
310
+ operation: "refresh",
311
+ cause
312
+ }))))) return Option.none();
313
+ }
314
+ return Option.some(observed);
315
+ }).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)));
316
+ return RefreshOutcome.Observed({ outcome: completed.outcome });
317
+ })
318
+ });
318
319
  });
320
+ const refresh = (watcher) => watcher.lock.withPermit(Ref.get(watcher.lifecycle).pipe(Effect.flatMap(refreshCurrent)));
319
321
  const confectStructureWatcher = Effect.fnUntraced(function* (signal, pendingRef, restart, restartEntry) {
320
322
  const fs = yield* FileSystem.FileSystem;
321
323
  const path = yield* Path.Path;
@@ -373,6 +375,6 @@ const handleConfectChange = ({ relativePath, eventTag, signal, pendingRef, resta
373
375
  return Match.value(eventTag).pipe(Match.when("Create", () => flipDirtyAndSignal(pendingRef, signal, restart, false)), Match.whenOr("Update", "Remove", () => Effect.void), Match.exhaustive);
374
376
  };
375
377
  //#endregion
376
- export { OperationError, isRefreshSuccessful, make, parseFailure };
378
+ export { CoalesceQuiescence, OperationError, isRefreshSuccessful, make, parseFailure };
377
379
 
378
380
  //# sourceMappingURL=Watcher.mjs.map
@@ -1 +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\";\nimport * as WatchBuild from \"./WatchBuild\";\nimport * as WatchTopology from \"./WatchTopology\";\nimport * as SyncState from \"./SyncState\";\nimport type { Pending } from \"./SyncState\";\nimport * as EntryPoint from \"./EntryPoint\";\nimport type { EntryPoint as Entry } from \"./EntryPoint\";\nimport { ConfectDirectory } from \"./ConfectDirectory\";\nimport { CONVEX_CONFIG_FILENAME } from \"./ConvexConfig\";\nimport { ConvexDirectory } from \"./ConvexDirectory\";\nimport { ProjectRoot } from \"./ProjectRoot\";\nimport * as RestoreWatcher from \"./RestoreWatcher\";\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* 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 refresh = Effect.fnUntraced(function* (watcher: State) {\n return yield* watcher.lock.withPermit(\n Effect.gen(function* () {\n const current = yield* Ref.get(watcher.lifecycle);\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(\n currentProgress,\n identifyRequest(promise),\n ),\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(\n Effect.ensuring(Ref.update(progress, WatchBuild.endRequest)),\n );\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 );\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAM,sBAAsB,SAAS,OAAO,GAAG;AAI/C,MAAM,oBAAoB,SAAS,QAAQ,CAAC;AAoB5C,MAAM,mBAAmB,KAAK,WAA6B;AAe3D,MAAM,iBAAiB,KAAK,WAA2B;AAEvD,MAAa,uBAAuB,YAClC,eAAe,OAAO,SAAS;CAC7B,aAAa;CACb,WAAW,EAAE,SAAS,eAAA,QACD,OAAO,UAAU;EAClC,iBAAiB;EACjB,cAAc;CAChB,CAAC;AACL,CAAC;AAEH,IAAa,iBAAb,cAAoC,OAAO,YAA4B,CAAC,CACtE,yBACA;CACE,WAAW,OAAO,SAAS;EACzB;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,OAAO,OAAO;AAChB,CACF,CAAC,CAAC,CAAC;AAEH,MAAM,uBAAuB,OAAO,OAAO,EACzC,QAAQ,OAAO,cAAc,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC,CAAC,EACrE,CAAC;AACD,MAAa,eAAe,OAAO,oBAAoB,oBAAoB;AAE3E,MAAa,OAAO,OAAO,WAAW,aAAa;CACjD,MAAM,SAAS,OAAO,MAAM,QAAc,CAAC;CAC3C,MAAM,aAAa,OAAO,IAAI,KAAcA,KAAe;CAC3D,MAAM,eAAe,OAAO,MAAM,QAAc,CAAC;CACjD,MAAM,QAAe;EACnB,WAAW,OAAO,IAAI,KACpB,iBAAiB,cAAc,CACjC;EACA,aAAa,OAAO,IAAI,KAAA,MAAwC,QAAQ,CAAC;EACzE,MAAM,OAAO,UAAU,KAAK,CAAC;EAC7B,UAAU,OAAOC,OAAmB,UAAU;EAC9C,UAAU,OAAO,IAAI,KAAK,KAAK;CACjC;CACA,MAAM,eAAe,iBACnB,aAAa,KACX,OAAO,QAAQ,MAAM,MAAM,cAAc,KAAA,CAAS,CAAC,GACnD,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CAC/C;CACF,MAAM,UAAU,YAAY,MAAM,SAAS,UAAU;CACrD,MAAM,gBAAgB,UACpB,YAAY,MAAM,SAAS,gBAAgB,KAAK,CAAC;CACnD,MAAM,mBAAmB,OAAO,IAAI,KAElC,OAAO,IAAI;CACb,OAAO;EACL,KAAK,OAAO,IAAI,aAAa;GAC3B,MAAM,YAAY,OAAOC,OACvB,wBAAwB,QAAQ,YAAY,SAAS,YAAY,CACnE;GACA,OAAO,IAAI,IAAI,kBAAkB,UAAU,aAAa;GACxD,OAAO,OAAO,IACZ;IACE,OAAO,OACL,mBAAmB,QAAQ,YAAY,cAAc,KAAK,CAC5D;IACA,UAAU;IACV,6BAA6B,SAAS,MAAM,QAAQ;GACtD,GACA,EAAE,aAAa,YAAY,CAC7B;EACF,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;EACrB,eAAe,OAAO,QAAQ,IAAI,IAAI,gBAAgB,CAAC;EAGvD,sBAAsB,QAAQ,KAAK,CAAC,CAAC,KACnC,OAAO,QACP,OAAO,QAAQ,IAAI,IAAI,YAAYF,KAAe,CAAC,CACrD;EACA,SAAS,QAAQ,KAAK;EACtB,MAAM,MAAM,KAAK,MAAM,CAAC,CAAC,KACvB,OAAO,QACL,oBAAoB,QAAQ,qBAAqB,iBAAiB,CACpE,GACA,OAAO,QAAQ,MAAM,SAAS,WAAW,GACzC,OAAO,kBAAkB,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CACzD;EACA,SAAS,IAAI,IAAI,UAAU;EAC3B,cAAc,IAAI,OAAO,YAAYG,IAAc,CAAC,CAAC,KACnD,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,GAC7C,OAAO,MACT;EACA,aAAa,IAAI,IAAI,MAAM,WAAW,CAAC,CAAC,KACtC,OAAO,IAAIC,WAAsB,CACnC;CACF;AACF,CAAC;AAID,MAAM,sBAAsB,OAAO,WAAW,WAC5C,QACA,YACA,SACA;CACA,MAAM,QAAQ,OAAO,MAAM;CAC3B,MAAM,YAAY,SAAS,SAAS,OAAO;CAC3C,MAAM,OAA4B,OAAO,IAAI,aAAa;EACxD,OAAO,OAAO,MAAM,UAAU;EAE9B,KAAI,OADmB,MAAM,MAAM,MAAM,EAAA,CAC7B,WAAW,GAAG;EAE1B,KAAI,OADe,MAAM,qBACf,QAAQ,WAChB,OAAO;CAEX,CAAC;CACD,OAAO;AACT,CAAC;AAED,MAAM,kBACJ,MACA,IACA,QACA,aACA,oBACA,SACA,aACA,UACA,YACA,aACA,QACA,YACA,YACyB;CACzB,MAAM,eAAe,OAAO,WAAW,OAAO,eAAe,OAAO,MAAM,CAAC;CAC3E,OAAO;EACL,eAAe;EACf,OAAO;GACL,UAAU,QACP,KAAK,UAAU,UAAU,aAAa,MAAM,YAAY,EAAE,EAAE,CAAC,CAC7D,KAAK,IAAI;GACZ,YAAY;GACZ,YAAY;GACZ,QAAQ;EACV;EACA,QAAQ;EACR,OAAO;EACP,UAAU;EACV,UAAU;EACV,QAAQ;EACR,UAAU;EACV,SAAS;GACPC,sBAA8B,MAAM,IAAI,WAAW;GACnD,eAAe,EAAE,aAAa,CAAC,GAAG,WAAW,EAAE,CAAC;GAChD;IACE,MAAM;IACN,MAAM,OAAO;KACX,MAAM,cACJ,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,OAAO,IAAI,OAAO,aAAaC,KAAgB;MAC/C,OAAO,IAAI,IAAI,YAAYC,YAAuB;KACpD,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,KAAA,CAAS,CAAC,CAC9B,CACF;KACA,MAAM,OAAO,EAAE,QAAQ,KAAK,IAAI,SAC9B,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,MAAM,cAAc,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,KAChD,OAAO,SAAS,aACd,OAAO,OAAO,WAAW,QAAQ,CACnC,GACA,OAAO,IAAI,IAAI,MAAM,GACrB,OAAO,MACT;MACA,OAAO,IAAI,OAAO,aAAa,YAC7B,OAAO,UAAU,WAAW,IACxB;OACE,GAAG;OACH,cAAc,QAAQ,IACpB,QAAQ,cACR,KAAK,MACL,YAAY,OACd;MACF,IACA;OACE,GAAG;OACH,UAAU,QAAQ,IAChB,QAAQ,UACR,KAAK,MAAA,QACc,mBAAmB;QACpC,MAAM,KAAK;QACX,OAAO,YAAY;OACrB,CAAC,CACH;MACF,CACN;KACF,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,KAAA,CAAS,CAAC,CAC9B,CACF;KACA,MAAM,OAAO,WACX,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,MAAM,EAAE,eAAe,OAAO,IAAI,IAAI,WAAW;MACjD,MAAM,WAAW,OAAO,IAAI,IAAI,QAAQ;MACxC,MAAM,UAAU,OAAOC,QACrB,QACA,OAAO,IAAI,IAAI,UAAU,IACxB,SAAS,KAAK,QAAQ,aAAa,IAAI,GACxC,MACF;MACA,MAAM,UAAUC,QAAmB,UAAU,OAAO;MACpD,OAAO,IAAI,IAAI,UAAU,OAAO;MAChC,MAAM,SAASC,KACb,UACA,SACA,qBAAqB,KAAK,GAC5B;MACA,OAAO,IAAI,OAAO,aAAa,YAAA,OACX,OAAO,QAAQ;OAC/B,YAAYC,IAAc,SAAS,SAAS,IAAI;OAChD,WAAW,EAAE,YACXA,IACE,SACA,QAAQ,QAAQ,UACd,QAAQ,IAAI,OAAO,MAAM,SAAS,CACpC,CACF;OACF,YAAY,EAAE,YACZC,UACED,IACE,SACA,QAAQ,QAAQ,UACd,QAAQ,IAAI,OAAO,MAAM,SAAS,CACpC,CACF,CACF;MACJ,CAAC,CACH;MACA,OAAO,MAAM,MAAM,QAAQ,KAAA,CAAS;MACpC,OAAO,IAAI,OAAO,cAAc,aAC9BE,SAAoB,UAAU;OAAE;OAAY;MAAQ,CAAC,CACvD;MACA,OAAO,SAAS,QAAQ,SAAS,KAAA,CAAS;KAC5C,CAAC,CACH,CACF;IACF;GACF;EACF;CACF;AACF;AAEA,MAAM,qBAAqB,OAAO,WAAW,WAC3C,QACA,YACA,cACA,SACA;CACA,MAAM,cAAc,OAAO,OAAO;CAClC,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,cAAc,OAAO,YAAY;CACvC,MAAM,mBAAmB,OAAO,iBAAiB;CACjD,MAAM,qBAAqB,KAAK,KAC9B,OAAO,GAAG,SAAS,gBAAgB,GACnC,YACF;CACA,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,mBAAmB,SAAS,KAAW,CAAC,CAAC,KAC7C,OAAO,KAAK,YAAY,SAAS,QAAQ,SAAS,KAAA,CAAS,CAAC,CAC9D;CAEA,MAAM,OAAO,OAAO,IAAI,aAAa;EACnC,MAAM,WAAW,OAAO,QAAQ,SAAS;EACzC,MAAM,UAAU,OAAO,IAAI,IAAI,QAAQ,SAAS;EAChD,MAAM,UAAU,OAAOC;EACvB,OAAO,IAAI,IAAI,QAAQ,UAAU,QAAQ,KAAA,KAAqB,IAAI,KAAK,CAAC,CAAC;EACzE,MAAM,eAAe,QAAQ,aAC3B,QAAQ,KAAK,UAAU,MAAM,YAAY,CAC3C;EACA,MAAM,MAAM,KACV,MAAM,aAAa,YAAY,GAC/B,MAAM,KAAK,MAAM,MAAM,GACvB,MAAM,KAAK,IAAI,CACjB;EAMA,IALkB,iBAAiB,OAAO,SAAS;GACjD,qBAAqB;GACrB,aAAa,QAAQ,WAAW;GAChC,SAAS,EAAE,KAAK,kBAAkB,gBAAgB;EACpD,CACY,GAAG;GACb,MAAM,UAAU,OAAO,iBAAiB,OAAO,SAAS;IACtD,qBAAqB;IACrB,aAAa;IACb,SAAS,EAAE,SAAS,oBAAoB,OAAO,QAAQ,aAAa;GACtE,CAAC;GACD,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;GACnD;EACF;EACA,OAAO,iBAAiB,OAAO,SAAS;GACtC,qBAAqB,OAAO;GAC5B,aAAa,IAAI,OAAO,YAAYX,IAAc;GAClD,SAAS,EAAE,SAAS,iBAAiB,YACnC,OAAO,IAAI,aAAa;IACtB,MAAM,kBAAkB,gBAAgB,QACrC,UACCY,WAAsB,KAAK,KAC3B,CAAC,QAAQ,IAAI,cAAc,MAAM,YAAY,CACjD;IACA,OAAO,IAAI,OAAO,aAAa,YAC7BJ,IAAcR,KAAe,OAAO,GAAG,eAAe,CACxD;IACA,OAAO,MAAM,MAAM,OAAO,KAAK,IAAI;GACrC,CAAC;EACL,CAAC;EACD,OAAO,IAAI,IAAI,QAAQ,WAAW,iBAAiB,cAAc,CAAC;EAClE,OAAO,IAAI,IAAI,QAAQ,aAAA,MAA8B,QAAQ,CAAC;EAC9D,IAAI,CAAC,MAAM,wBAAwB,OAAO,GAAG;GAC3C,OAAO,IAAI,IAAI,QAAQ,WAAW,iBAAiB,MAAM,CAAC;GAC1D,OAAO,IAAI,OAAO,YAAYA,IAAc;GAC5C,OAAO,MAAM,MAAM,QAAQ,KAAA,CAAS;GACpC,MAAM,UAAU,OAAO;GACvB,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;GACnD;EACF;EAEA,MAAM,QAAQ,OAAO,MAAM,KAAK,aAAa,YAAY;EACzD,MAAM,aAAa,OAAO,IAAI,KAAKI,YAAuB;EAC1D,MAAM,WAAW,OAAO,IAAI,KAAKS,eAA0B;EAC3D,MAAM,UAAU,OAAO,SAAS,KAAW;EAC3C,MAAM,WAAW,aAAa,WAAW;EACzC,MAAM,cAAc,sBAClB,UAAU,KAAK,iBAAiB,SAAS,CAAC,CAC5C;EACA,MAAM,UAAU,OAAO,OAAO,eAC5B,OAAO,WAAW;GAChB,WACE,QAAQ,QACN,eACE,MACA,IACA,QACA,aACA,oBACA,SACA,aACA,QAAQ,aACR,YACA,UACA,QACA,YACA,OACF,CACF;GACF,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAU;GAAM,CAAC;EACrE,CAAC,IACA,QACC,OAAO,WAAW;GAChB,WAAW,IAAI,QAAQ;GACvB,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAW;GAAM,CAAC;EACtE,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,CACxB,CAAC,CAAC,KAAK,MAAM,QAAQ,KAAK,CAAC;EAC3B,MAAM,6BAAa,IAAI,QAGrB;EACF,OAAO,IAAI,IACT,QAAQ,WACR,iBAAiB,OAAO;GACtB;GACA;GACA;GACA;GACA;GACA,kBAAkB,YAAY;IAC5B,MAAM,WAAW,WAAW,IAAI,OAAO;IACvC,IAAI,aAAa,KAAA,GAAW,OAAO;IACnC,MAAM,KAAKC,cAAyB;IACpC,WAAW,IAAI,SAAS,EAAE;IAC1B,OAAO;GACT;GACA;GACA,eAAe,aACbC,aAAwB,UAAU,IAAI,MAAM;EAChD,CAAC,CACH;EACA,OAAO,OAAO,WAAW;GACvB,WAAW,QAAQ,MAAM;GACzB,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAS;GAAM,CAAC;EACpE,CAAC;EACD,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;CACrD,CAAC,CAAC,CAAC,KAAK,UAAU,WAAW,QAAQ,IAAI,CAAC;CAE1C,OAAO;CACP,OAAO,OAAO,OAAO,QACnB,MAAM,KAAK,YAAY,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC,CACpD;AACF,GAAG,OAAO,QAAQ,WAAW,KAAK,CAAC;AAEnC,MAAM,UAAU,OAAO,WAAW,WAAW,SAAgB;CAC3D,OAAO,OAAO,QAAQ,KAAK,WACzB,OAAO,IAAI,aAAa;EACtB,MAAM,UAAU,OAAO,IAAI,IAAI,QAAQ,SAAS;EAChD,OAAO,OAAO,iBAAiB,OAAO,SAAS;GAC7C,aAAa,OAAO,QAAQ,eAAe,MAAM,CAAC;GAClD,qBACE,OAAO,KACL,IAAI,eAAe;IACjB,WAAW;IACX,OAAO;GACT,CAAC,CACH;GACF,SAAS,EAAE,SAAS,iBAAiB,UAAU,mBAC7C,OAAO,IAAI,aAAa;IACtB,MAAM,UAAU,OAAO,YAAY,OAAO,OAAO,QAAQ,CAAC;IAC1D,MAAM,UAAUC,eAA0B,OAAO,IAAI,IAAI,QAAQ,CAAC;IA+DlE,MAAM,YAAY,OA9DF,OAAO,IAAI,aAAa;KACtC,MAAM,QAAQ,OAAO,OAAO,WAAW;MACrC,WAAW;OACT,MAAM,UAAU,QAAQ,QAAQ;OAChC,QACE,IAAI,OAAO,WAAW,oBACpBC,QACE,iBACA,gBAAgB,OAAO,CACzB,CACF,CACF;OACA,OAAO;MACT;MACA,QAAQ,UACN,IAAI,eAAe;OAAE,WAAW;OAAW;MAAM,CAAC;KACtD,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;KACrB,MAAM,kBAAkB,OAAO,IAAI,IAAI,QAAQ;KAC/C,MAAM,YAAYC,cAAyB,eAAe;KAC1D,IAAI,OAAO,UAAU,KAAK,GAAG;MAC3B,MAAM,WAAW,aAAa,MAAM,QAAQ,KAAK;MACjD,IAAI,OAAO,OAAO,QAAQ,GAAG,OAAO,OAAO,MAAM;MACjD,IAAIC,wBAAmC,eAAe,GACpD,OAAO,OAAO,KAA4B;MAC5C,IACE,OAAO,OAAO,SAAS,KACvB,CAAA,QAAoB,IAAI,QAAQ,CAAC,CAAC,UAAU,MAAM,OAAO,GAEzD,OAAO,OAAO,IAAI,eAAe;OAC/B,WAAW;OACX,OAAO,SAAS,MAAM;MACxB,CAAC;KACL;KACA,IAAIA,wBAAmC,eAAe,GACpD,OAAO,OAAO,KAA4B;KAC5C,MAAM,WAAW,OAAO,OAAO,WAAW,SAAS,CAAC,CAAC,KACnD,OAAO,eAEH,IAAI,eAAe;MACjB,WAAW;MACX,OAAO;KACT,CAAC,CACL,CACF;KACA,IACEC,QAAmB,SAAS,QAAQ,KAAA,QACjB,IAAI,WAAW,CAAC,CAAC,SAAS,OAAO,GAUhD;UAAA,EAAC,OARoB,aACvB,SAAS,QAAQ,QACnB,CAAC,CAAC,KACA,OAAO,UACJ,EAAE,YACD,IAAI,eAAe;OAAE,WAAW;OAAW;MAAM,CAAC,CACtD,CACF,IACgB,OAAO,OAAO,KAA4B;KAAA;KAE5D,OAAO,OAAO,KAAK,QAAQ;IAC7B,CAAC,CAAC,CAAC,KACD,OAAO,SAAS,IAAI,OAAO,UAAUC,UAAqB,CAAC,CAE9B,CAAC,CAAC,KAC/B,OAAO,OAAO,EACZ,QAAQ,aACN,OAAO,OAAO,QAAQ,KACtB,CAACD,QAAmB,SAAS,SAAS,KAAK,EAC/C,CAAC,GACD,OAAO,SAAS,aACd,OAAO,WAAW,QAAQ,CAAC,CAAC,KAAK,OAAO,KAAK,CAC/C,CACF;IACA,OAAO,eAAe,SAAS,EAAE,SAAS,UAAU,QAAQ,CAAC;GAC/D,CAAC;EACL,CAAC;CACH,CAAC,CACH;AACF,CAAC;AAED,MAAM,0BAA0B,OAAO,WAAW,WAChD,QACA,YACA,SACA,cACA;CACA,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,mBAAmB,OAAO,iBAAiB;CACjD,MAAM,mBAAmB,OAAO,OAAO;EACrC,MAAM,OAAO,QAAQ,QAAQ;EAC7B,SAAS,OAAO,QAAQ,SAAS;EACjC,MAAM,OAAO;CACf,CAAC;CAED,OAAO,KACL,GAAG,MAAM,kBAAkB,EAAE,WAAW,KAAK,CAAC,GAC9C,OAAO,YAAY,UACjB,oBAAoB;EAClB,cAAc,KAAK,SACjB,kBACA,KAAK,QAAQ,kBAAkB,MAAM,IAAI,CAC3C;EACA,UAAU,MAAM;EAChB;EACA;EACA;EACA;CACF,CAAC,CACH,GACA,OAAO,MAAM;EACX,UAAU,SAAS,OAAO,WAAW;EACrC,QAAQ,UACN,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,oBAAoB,gBAAgB,CAAC,CAC1D,MAAM,OAAO,KACf;GACA,IAAI,OAAO,OAAO,OAAO,GAAG,OAAO;GACnC,MAAM,WAAW,KAAK,SAAS,kBAAkB,QAAQ,MAAM,IAAI;GACnE,IACE,aAAa,MACb,aAAa,QACb,SAAS,WAAW,KAAK,KAAK,KAAK,KACnC,KAAK,WAAW,QAAQ,GAExB,OAAO;GACT,IACE,EAAE,OAAO,GACN,OAAO,gBAAgB,CAAC,CACxB,KAAK,OAAO,oBAAoB,KAAK,CAAC,IAEzC,OAAO;GAET,OAAO;GACP,OAAO;EACT,CAAC;CACL,CAAC,CACH;AACF,CAAC;;;;;;;;;AAUD,MAAM,+BAA+B,OAAO,WAAW,WACrD,SACA,UACA;CACA,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,kBAAkB,OAAO,gBAAgB;CAE/C,OAAO,KACL,GAAG,MAAM,eAAe,GACxB,OAAO,YAAY,UACjB,OAAO,IAAI,aAAa;EAGtB,IACE,KAAK,SAAS,iBAAiB,MAAM,IAAI,MAAA,uBAExC,OAAO,IAAI,IAAI,QAAQ,IAExB;EACF,OAAO,MAAM,MAAM,KAAK,CAAC,CAAC,KACxB,MAAM,IAAI,gBAAgB,OAAO,IAAI,GACrC,MAAM,IAAI,UAAU,gBAAgB,OAAO,GAC3C,MAAM,UACR;CACF,CAAC,CACH,CACF;AACF,CAAC;AAED,MAAM,sBACJ,YACA,QACA,SACA,sBAEA,oBACI,UACA,IAAI,OAAO,YAAYpB,IAAc,CAAC,CAAC,KACrC,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CAC/C;AAEN,MAAM,uBAAuB,EAC3B,cACA,UACA,QACA,YACA,SACA,mBAQI;CACJ,IAAI,aAAa,MAAM,OAAO,CAAC,CAAC,SAAS,YAAY,GACnD,OAAO,OAAO;CAGhB,IAAI,CAAC,aAAa,SAAS,KAAK,GAC9B,OAAO,OAAO;CAGhB,MAAM,oBAAoB,MAAM,MAAM,QAAQ,CAAC,CAAC,KAC9C,MAAM,KAAK,gBAAgB,KAAK,GAChC,MAAM,OAAO,UAAU,gBAAgB,IAAI,GAC3C,MAAM,UACR;CAEA,MAAM,QAAQsB,MAAiB,YAAY;CAC3C,IAAI,OAAO,OAAO,KAAK,GACrB,OAAO,oBAAoB,aAAa,MAAM,KAAK,IAAI,OAAO;CAOhE,IAAI,iBAAiB,aACnB,OAAO,mBAAmB,YAAY,QAAQ,SAAS,iBAAiB;CAS1E,OAAO,MAAM,MAAM,QAAQ,CAAC,CAAC,KAC3B,MAAM,KAAK,gBACT,mBAAmB,YAAY,QAAQ,SAAS,KAAK,CACvD,GACA,MAAM,OAAO,UAAU,gBAAgB,OAAO,IAAI,GAClD,MAAM,UACR;AACF"}
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 Context from \"effect/Context\";\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\nexport const CoalesceQuiescence = Context.Reference<Duration.Duration>(\n \"@confect/cli/Watcher/CoalesceQuiescence\",\n { defaultValue: () => Duration.millis(50) },\n);\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 quiescence = yield* CoalesceQuiescence;\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, 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 const elapsed = (yield* Clock.currentTimeMillis) - start;\n yield* Effect.sleep(\n Duration.millis(\n Math.min(\n Duration.toMillis(quiescence),\n Math.max(0, maxMillis - elapsed),\n ),\n ),\n );\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,MAAa,qBAAqB,QAAQ,UACxC,2CACA,EAAE,oBAAoB,SAAS,OAAO,EAAE,EAAE,CAC5C;AAIA,MAAM,oBAAoB,SAAS,QAAQ,CAAC;AAoB5C,MAAM,mBAAmB,KAAK,WAA6B;AAe3D,MAAM,iBAAiB,KAAK,WAA2B;AAEvD,MAAa,uBAAuB,YAClC,eAAe,OAAO,SAAS;CAC7B,aAAa;CACb,WAAW,EAAE,SAAS,eAAA,QACD,OAAO,UAAU;EAClC,iBAAiB;EACjB,cAAc;CAChB,CAAC;AACL,CAAC;AAEH,IAAa,iBAAb,cAAoC,OAAO,YAA4B,CAAC,CACtE,yBACA;CACE,WAAW,OAAO,SAAS;EACzB;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,OAAO,OAAO;AAChB,CACF,CAAC,CAAC,CAAC;AAEH,MAAM,uBAAuB,OAAO,OAAO,EACzC,QAAQ,OAAO,cAAc,OAAO,OAAO,EAAE,MAAM,OAAO,OAAO,CAAC,CAAC,EACrE,CAAC;AACD,MAAa,eAAe,OAAO,oBAAoB,oBAAoB;AAE3E,MAAa,OAAO,OAAO,WAAW,aAAa;CACjD,MAAM,aAAa,OAAO;CAC1B,MAAM,SAAS,OAAO,MAAM,QAAc,CAAC;CAC3C,MAAM,aAAa,OAAO,IAAI,KAAcA,KAAe;CAC3D,MAAM,eAAe,OAAO,MAAM,QAAc,CAAC;CACjD,MAAM,QAAe;EACnB,WAAW,OAAO,IAAI,KACpB,iBAAiB,cAAc,CACjC;EACA,aAAa,OAAO,IAAI,KAAA,MAAwC,QAAQ,CAAC;EACzE,MAAM,OAAO,UAAU,KAAK,CAAC;EAC7B,UAAU,OAAOC,OAAmB,UAAU;EAC9C,UAAU,OAAO,IAAI,KAAK,KAAK;CACjC;CACA,MAAM,eAAe,iBACnB,aAAa,KACX,OAAO,QAAQ,MAAM,MAAM,cAAc,KAAA,CAAS,CAAC,GACnD,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CAC/C;CACF,MAAM,UAAU,YAAY,MAAM,SAAS,UAAU;CACrD,MAAM,gBAAgB,UACpB,YAAY,MAAM,SAAS,gBAAgB,KAAK,CAAC;CACnD,MAAM,mBAAmB,OAAO,IAAI,KAElC,OAAO,IAAI;CACb,OAAO;EACL,KAAK,OAAO,IAAI,aAAa;GAC3B,MAAM,YAAY,OAAOC,OACvB,wBAAwB,QAAQ,YAAY,SAAS,YAAY,CACnE;GACA,OAAO,IAAI,IAAI,kBAAkB,UAAU,aAAa;GACxD,OAAO,OAAO,IACZ;IACE,OAAO,OACL,mBAAmB,QAAQ,YAAY,cAAc,KAAK,CAC5D;IACA,UAAU;IACV,6BAA6B,SAAS,MAAM,QAAQ;GACtD,GACA,EAAE,aAAa,YAAY,CAC7B;EACF,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;EACrB,eAAe,OAAO,QAAQ,IAAI,IAAI,gBAAgB,CAAC;EAGvD,sBAAsB,QAAQ,KAAK,CAAC,CAAC,KACnC,OAAO,QACP,OAAO,QAAQ,IAAI,IAAI,YAAYF,KAAe,CAAC,CACrD;EACA,SAAS,QAAQ,KAAK;EACtB,MAAM,MAAM,KAAK,MAAM,CAAC,CAAC,KACvB,OAAO,QACL,oBAAoB,QAAQ,YAAY,iBAAiB,CAC3D,GACA,OAAO,QAAQ,MAAM,SAAS,WAAW,GACzC,OAAO,kBAAkB,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CACzD;EACA,SAAS,IAAI,IAAI,UAAU;EAC3B,cAAc,IAAI,OAAO,YAAYG,IAAc,CAAC,CAAC,KACnD,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,GAC7C,OAAO,MACT;EACA,aAAa,IAAI,IAAI,MAAM,WAAW,CAAC,CAAC,KACtC,OAAO,IAAIC,WAAsB,CACnC;CACF;AACF,CAAC;AAID,MAAM,sBAAsB,OAAO,WAAW,WAC5C,QACA,YACA,SACA;CACA,MAAM,QAAQ,OAAO,MAAM;CAC3B,MAAM,YAAY,SAAS,SAAS,OAAO;CAC3C,MAAM,OAA4B,OAAO,IAAI,aAAa;EACxD,MAAM,WAAW,OAAO,MAAM,qBAAqB;EACnD,OAAO,OAAO,MACZ,SAAS,OACP,KAAK,IACH,SAAS,SAAS,UAAU,GAC5B,KAAK,IAAI,GAAG,YAAY,OAAO,CACjC,CACF,CACF;EAEA,KAAI,OADmB,MAAM,MAAM,MAAM,EAAA,CAC7B,WAAW,GAAG;EAE1B,KAAI,OADe,MAAM,qBACf,QAAQ,WAChB,OAAO;CAEX,CAAC;CACD,OAAO;AACT,CAAC;AAED,MAAM,kBACJ,MACA,IACA,QACA,aACA,oBACA,SACA,aACA,UACA,YACA,aACA,QACA,YACA,YACyB;CACzB,MAAM,eAAe,OAAO,WAAW,OAAO,eAAe,OAAO,MAAM,CAAC;CAC3E,OAAO;EACL,eAAe;EACf,OAAO;GACL,UAAU,QACP,KAAK,UAAU,UAAU,aAAa,MAAM,YAAY,EAAE,EAAE,CAAC,CAC7D,KAAK,IAAI;GACZ,YAAY;GACZ,YAAY;GACZ,QAAQ;EACV;EACA,QAAQ;EACR,OAAO;EACP,UAAU;EACV,UAAU;EACV,QAAQ;EACR,UAAU;EACV,SAAS;GACPC,sBAA8B,MAAM,IAAI,WAAW;GACnD,eAAe,EAAE,aAAa,CAAC,GAAG,WAAW,EAAE,CAAC;GAChD;IACE,MAAM;IACN,MAAM,OAAO;KACX,MAAM,cACJ,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,OAAO,IAAI,OAAO,aAAaC,KAAgB;MAC/C,OAAO,IAAI,IAAI,YAAYC,YAAuB;KACpD,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,KAAA,CAAS,CAAC,CAC9B,CACF;KACA,MAAM,OAAO,EAAE,QAAQ,KAAK,IAAI,SAC9B,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,MAAM,cAAc,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,KAChD,OAAO,SAAS,aACd,OAAO,OAAO,WAAW,QAAQ,CACnC,GACA,OAAO,IAAI,IAAI,MAAM,GACrB,OAAO,MACT;MACA,OAAO,IAAI,OAAO,aAAa,YAC7B,OAAO,UAAU,WAAW,IACxB;OACE,GAAG;OACH,cAAc,QAAQ,IACpB,QAAQ,cACR,KAAK,MACL,YAAY,OACd;MACF,IACA;OACE,GAAG;OACH,UAAU,QAAQ,IAChB,QAAQ,UACR,KAAK,MAAA,QACc,mBAAmB;QACpC,MAAM,KAAK;QACX,OAAO,YAAY;OACrB,CAAC,CACH;MACF,CACN;KACF,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,KAAA,CAAS,CAAC,CAC9B,CACF;KACA,MAAM,OAAO,WACX,OAAO,WACL,OAAO,IAAI,aAAa;MACtB,MAAM,EAAE,eAAe,OAAO,IAAI,IAAI,WAAW;MACjD,MAAM,WAAW,OAAO,IAAI,IAAI,QAAQ;MACxC,MAAM,UAAU,OAAOC,QACrB,QACA,OAAO,IAAI,IAAI,UAAU,IACxB,SAAS,KAAK,QAAQ,aAAa,IAAI,GACxC,MACF;MACA,MAAM,UAAUC,QAAmB,UAAU,OAAO;MACpD,OAAO,IAAI,IAAI,UAAU,OAAO;MAChC,MAAM,SAASC,KACb,UACA,SACA,qBAAqB,KAAK,GAC5B;MACA,OAAO,IAAI,OAAO,aAAa,YAAA,OACX,OAAO,QAAQ;OAC/B,YAAYC,IAAc,SAAS,SAAS,IAAI;OAChD,WAAW,EAAE,YACXA,IACE,SACA,QAAQ,QAAQ,UACd,QAAQ,IAAI,OAAO,MAAM,SAAS,CACpC,CACF;OACF,YAAY,EAAE,YACZC,UACED,IACE,SACA,QAAQ,QAAQ,UACd,QAAQ,IAAI,OAAO,MAAM,SAAS,CACpC,CACF,CACF;MACJ,CAAC,CACH;MACA,OAAO,MAAM,MAAM,QAAQ,KAAA,CAAS;MACpC,OAAO,IAAI,OAAO,cAAc,aAC9BE,SAAoB,UAAU;OAAE;OAAY;MAAQ,CAAC,CACvD;MACA,OAAO,SAAS,QAAQ,SAAS,KAAA,CAAS;KAC5C,CAAC,CACH,CACF;IACF;GACF;EACF;CACF;AACF;AAEA,MAAM,qBAAqB,OAAO,WAAW,WAC3C,QACA,YACA,cACA,SACA;CACA,MAAM,cAAc,OAAO,OAAO;CAClC,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,cAAc,OAAO,YAAY;CACvC,MAAM,mBAAmB,OAAO,iBAAiB;CACjD,MAAM,qBAAqB,KAAK,KAC9B,OAAO,GAAG,SAAS,gBAAgB,GACnC,YACF;CACA,MAAM,SAAS,OAAO,OAAO;CAC7B,MAAM,mBAAmB,SAAS,KAAW,CAAC,CAAC,KAC7C,OAAO,KAAK,YAAY,SAAS,QAAQ,SAAS,KAAA,CAAS,CAAC,CAC9D;CAEA,MAAM,OAAO,OAAO,IAAI,aAAa;EACnC,MAAM,WAAW,OAAO,QAAQ,SAAS;EACzC,MAAM,UAAU,OAAO,IAAI,IAAI,QAAQ,SAAS;EAChD,MAAM,UAAU,OAAOC;EACvB,OAAO,IAAI,IAAI,QAAQ,UAAU,QAAQ,KAAA,KAAqB,IAAI,KAAK,CAAC,CAAC;EACzE,MAAM,eAAe,QAAQ,aAC3B,QAAQ,KAAK,UAAU,MAAM,YAAY,CAC3C;EACA,MAAM,MAAM,KACV,MAAM,aAAa,YAAY,GAC/B,MAAM,KAAK,MAAM,MAAM,GACvB,MAAM,KAAK,IAAI,CACjB;EAMA,IALkB,iBAAiB,OAAO,SAAS;GACjD,qBAAqB;GACrB,aAAa,QAAQ,WAAW;GAChC,SAAS,EAAE,KAAK,kBAAkB,gBAAgB;EACpD,CACY,GAAG;GACb,MAAM,UAAU,OAAO,iBAAiB,OAAO,SAAS;IACtD,qBAAqB;IACrB,aAAa;IACb,SAAS,EAAE,SAAS,oBAAoB,OAAO,QAAQ,aAAa;GACtE,CAAC;GACD,OAAO,eAAe,OAAO,CAAC,CAAC,KAC7B,OAAO,SAAS,+BACd,IAAI,OAAO,YAAYX,IAAc,CACvC,CACF;GACA,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;GACnD;EACF;EACA,OAAO,iBAAiB,OAAO,SAAS;GACtC,qBAAqB,OAAO;GAC5B,aAAa,IAAI,OAAO,YAAYA,IAAc;GAClD,SAAS,EAAE,SAAS,iBAAiB,YACnC,OAAO,IAAI,aAAa;IACtB,MAAM,kBAAkB,gBAAgB,QACrC,UACCY,WAAsB,KAAK,KAC3B,CAAC,QAAQ,IAAI,cAAc,MAAM,YAAY,CACjD;IACA,OAAO,IAAI,OAAO,aAAa,YAC7BJ,IAAcR,KAAe,OAAO,GAAG,eAAe,CACxD;IACA,OAAO,MAAM,MAAM,OAAO,KAAK,IAAI;GACrC,CAAC;EACL,CAAC;EACD,OAAO,IAAI,IAAI,QAAQ,WAAW,iBAAiB,cAAc,CAAC;EAClE,OAAO,IAAI,IAAI,QAAQ,aAAA,MAA8B,QAAQ,CAAC;EAC9D,IAAI,CAAC,MAAM,wBAAwB,OAAO,GAAG;GAC3C,OAAO,IAAI,IAAI,QAAQ,WAAW,iBAAiB,MAAM,CAAC;GAC1D,OAAO,IAAI,OAAO,YAAYA,IAAc;GAC5C,OAAO,MAAM,MAAM,QAAQ,KAAA,CAAS;GACpC,MAAM,UAAU,OAAO;GACvB,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;GACnD;EACF;EAEA,MAAM,QAAQ,OAAO,MAAM,KAAK,aAAa,YAAY;EACzD,MAAM,aAAa,OAAO,IAAI,KAAKI,YAAuB;EAC1D,MAAM,WAAW,OAAO,IAAI,KAAKS,eAA0B;EAC3D,MAAM,UAAU,OAAO,SAAS,KAAW;EAC3C,MAAM,WAAW,aAAa,WAAW;EACzC,MAAM,cAAc,sBAClB,UAAU,KAAK,iBAAiB,SAAS,CAAC,CAC5C;EACA,MAAM,UAAU,OAAO,OAAO,eAC5B,OAAO,WAAW;GAChB,WACE,QAAQ,QACN,eACE,MACA,IACA,QACA,aACA,oBACA,SACA,aACA,QAAQ,aACR,YACA,UACA,QACA,YACA,OACF,CACF;GACF,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAU;GAAM,CAAC;EACrE,CAAC,IACA,QACC,OAAO,WAAW;GAChB,WAAW,IAAI,QAAQ;GACvB,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAW;GAAM,CAAC;EACtE,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,CACxB,CAAC,CAAC,KAAK,MAAM,QAAQ,KAAK,CAAC;EAC3B,MAAM,6BAAa,IAAI,QAGrB;EACF,OAAO,IAAI,IACT,QAAQ,WACR,iBAAiB,OAAO;GACtB;GACA;GACA;GACA;GACA;GACA,kBAAkB,YAAY;IAC5B,MAAM,WAAW,WAAW,IAAI,OAAO;IACvC,IAAI,aAAa,KAAA,GAAW,OAAO;IACnC,MAAM,KAAKC,cAAyB;IACpC,WAAW,IAAI,SAAS,EAAE;IAC1B,OAAO;GACT;GACA;GACA,eAAe,aACbC,aAAwB,UAAU,IAAI,MAAM;EAChD,CAAC,CACH;EACA,OAAO,OAAO,WAAW;GACvB,WAAW,QAAQ,MAAM;GACzB,QAAQ,UAAU,IAAI,eAAe;IAAE,WAAW;IAAS;GAAM,CAAC;EACpE,CAAC;EACD,OAAO,QAAQ,SAAS,UAAU,UAAU,OAAO;CACrD,CAAC,CAAC,CAAC,KAAK,UAAU,WAAW,QAAQ,IAAI,CAAC;CAE1C,OAAO;CACP,OAAO,OAAO,OAAO,QACnB,MAAM,KAAK,YAAY,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC,CACpD;AACF,GAAG,OAAO,QAAQ,WAAW,KAAK,CAAC;AAEnC,MAAM,iBAAiB,OAAO,WAAW,WAAW,SAA2B;CAC7E,OAAO,OAAO,iBAAiB,OAAO,SAAS;EAC7C,aAAa,OAAO,QAAQ,eAAe,MAAM,CAAC;EAClD,qBACE,OAAO,KACL,IAAI,eAAe;GACjB,WAAW;GACX,OAAO;EACT,CAAC,CACH;EACF,SAAS,EAAE,SAAS,iBAAiB,UAAU,mBAC7C,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,YAAY,OAAO,OAAO,QAAQ,CAAC;GAC1D,MAAM,UAAUC,eAA0B,OAAO,IAAI,IAAI,QAAQ,CAAC;GA0DlE,MAAM,YAAY,OAzDF,OAAO,IAAI,aAAa;IACtC,MAAM,QAAQ,OAAO,OAAO,WAAW;KACrC,WAAW;MACT,MAAM,UAAU,QAAQ,QAAQ;MAChC,QACE,IAAI,OAAO,WAAW,oBACpBC,QAAmB,iBAAiB,gBAAgB,OAAO,CAAC,CAC9D,CACF;MACA,OAAO;KACT;KACA,QAAQ,UACN,IAAI,eAAe;MAAE,WAAW;MAAW;KAAM,CAAC;IACtD,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;IACrB,MAAM,kBAAkB,OAAO,IAAI,IAAI,QAAQ;IAC/C,MAAM,YAAYC,cAAyB,eAAe;IAC1D,IAAI,OAAO,UAAU,KAAK,GAAG;KAC3B,MAAM,WAAW,aAAa,MAAM,QAAQ,KAAK;KACjD,IAAI,OAAO,OAAO,QAAQ,GAAG,OAAO,OAAO,MAAM;KACjD,IAAIC,wBAAmC,eAAe,GACpD,OAAO,OAAO,KAA4B;KAC5C,IACE,OAAO,OAAO,SAAS,KACvB,CAAA,QAAoB,IAAI,QAAQ,CAAC,CAAC,UAAU,MAAM,OAAO,GAEzD,OAAO,OAAO,IAAI,eAAe;MAC/B,WAAW;MACX,OAAO,SAAS,MAAM;KACxB,CAAC;IACL;IACA,IAAIA,wBAAmC,eAAe,GACpD,OAAO,OAAO,KAA4B;IAC5C,MAAM,WAAW,OAAO,OAAO,WAAW,SAAS,CAAC,CAAC,KACnD,OAAO,eAEH,IAAI,eAAe;KACjB,WAAW;KACX,OAAO;IACT,CAAC,CACL,CACF;IACA,IACEC,QAAmB,SAAS,QAAQ,KAAA,QACjB,IAAI,WAAW,CAAC,CAAC,SAAS,OAAO,GAUhD;SAAA,EAAC,OARoB,aACvB,SAAS,QAAQ,QACnB,CAAC,CAAC,KACA,OAAO,UACJ,EAAE,YACD,IAAI,eAAe;MAAE,WAAW;MAAW;KAAM,CAAC,CACtD,CACF,IACgB,OAAO,OAAO,KAA4B;IAAA;IAE5D,OAAO,OAAO,KAAK,QAAQ;GAC7B,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,IAAI,OAAO,UAAUC,UAAqB,CAAC,CACpC,CAAC,CAAC,KAC/B,OAAO,OAAO,EACZ,QAAQ,aACN,OAAO,OAAO,QAAQ,KACtB,CAACD,QAAmB,SAAS,SAAS,KAAK,EAC/C,CAAC,GACD,OAAO,SAAS,aACd,OAAO,WAAW,QAAQ,CAAC,CAAC,KAAK,OAAO,KAAK,CAC/C,CACF;GACA,OAAO,eAAe,SAAS,EAAE,SAAS,UAAU,QAAQ,CAAC;EAC/D,CAAC;CACL,CAAC;AACH,CAAC;AAED,MAAM,WAAW,YACf,QAAQ,KAAK,WACX,IAAI,IAAI,QAAQ,SAAS,CAAC,CAAC,KAAK,OAAO,QAAQ,cAAc,CAAC,CAChE;AAEF,MAAM,0BAA0B,OAAO,WAAW,WAChD,QACA,YACA,SACA,cACA;CACA,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,mBAAmB,OAAO,iBAAiB;CACjD,MAAM,mBAAmB,OAAO,OAAO;EACrC,MAAM,OAAO,QAAQ,QAAQ;EAC7B,SAAS,OAAO,QAAQ,SAAS;EACjC,MAAM,OAAO;CACf,CAAC;CAED,OAAO,KACL,GAAG,MAAM,kBAAkB,EAAE,WAAW,KAAK,CAAC,GAC9C,OAAO,YAAY,UACjB,oBAAoB;EAClB,cAAc,KAAK,SACjB,kBACA,KAAK,QAAQ,kBAAkB,MAAM,IAAI,CAC3C;EACA,UAAU,MAAM;EAChB;EACA;EACA;EACA;CACF,CAAC,CACH,GACA,OAAO,MAAM;EACX,UAAU,SAAS,OAAO,WAAW;EACrC,QAAQ,UACN,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,oBAAoB,gBAAgB,CAAC,CAC1D,MAAM,OAAO,KACf;GACA,IAAI,OAAO,OAAO,OAAO,GAAG,OAAO;GACnC,MAAM,WAAW,KAAK,SAAS,kBAAkB,QAAQ,MAAM,IAAI;GACnE,IACE,aAAa,MACb,aAAa,QACb,SAAS,WAAW,KAAK,KAAK,KAAK,KACnC,KAAK,WAAW,QAAQ,GAExB,OAAO;GACT,IACE,EAAE,OAAO,GACN,OAAO,gBAAgB,CAAC,CACxB,KAAK,OAAO,oBAAoB,KAAK,CAAC,IAEzC,OAAO;GAET,OAAO;GACP,OAAO;EACT,CAAC;CACL,CAAC,CACH;AACF,CAAC;;;;;;;;;AAUD,MAAM,+BAA+B,OAAO,WAAW,WACrD,SACA,UACA;CACA,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CACzB,MAAM,kBAAkB,OAAO,gBAAgB;CAE/C,OAAO,KACL,GAAG,MAAM,eAAe,GACxB,OAAO,YAAY,UACjB,OAAO,IAAI,aAAa;EAGtB,IACE,KAAK,SAAS,iBAAiB,MAAM,IAAI,MAAA,uBAExC,OAAO,IAAI,IAAI,QAAQ,IAExB;EACF,OAAO,MAAM,MAAM,KAAK,CAAC,CAAC,KACxB,MAAM,IAAI,gBAAgB,OAAO,IAAI,GACrC,MAAM,IAAI,UAAU,gBAAgB,OAAO,GAC3C,MAAM,UACR;CACF,CAAC,CACH,CACF;AACF,CAAC;AAED,MAAM,sBACJ,YACA,QACA,SACA,sBAEA,oBACI,UACA,IAAI,OAAO,YAAYpB,IAAc,CAAC,CAAC,KACrC,OAAO,QAAQ,MAAM,MAAM,QAAQ,KAAA,CAAS,CAAC,CAC/C;AAEN,MAAM,uBAAuB,EAC3B,cACA,UACA,QACA,YACA,SACA,mBAQI;CACJ,IAAI,aAAa,MAAM,OAAO,CAAC,CAAC,SAAS,YAAY,GACnD,OAAO,OAAO;CAGhB,IAAI,CAAC,aAAa,SAAS,KAAK,GAC9B,OAAO,OAAO;CAGhB,MAAM,oBAAoB,MAAM,MAAM,QAAQ,CAAC,CAAC,KAC9C,MAAM,KAAK,gBAAgB,KAAK,GAChC,MAAM,OAAO,UAAU,gBAAgB,IAAI,GAC3C,MAAM,UACR;CAEA,MAAM,QAAQsB,MAAiB,YAAY;CAC3C,IAAI,OAAO,OAAO,KAAK,GACrB,OAAO,oBAAoB,aAAa,MAAM,KAAK,IAAI,OAAO;CAOhE,IAAI,iBAAiB,aACnB,OAAO,mBAAmB,YAAY,QAAQ,SAAS,iBAAiB;CAS1E,OAAO,MAAM,MAAM,QAAQ,CAAC,CAAC,KAC3B,MAAM,KAAK,gBACT,mBAAmB,YAAY,QAAQ,SAAS,KAAK,CACvD,GACA,MAAM,OAAO,UAAU,gBAAgB,OAAO,IAAI,GAClD,MAAM,UACR;AACF"}
@@ -1 +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\";\n\nexport const cliApp = Command.run(confect, {\n version: packageJson.version,\n});\n"],"mappings":";;;;AAIA,MAAa,SAAS,QAAQ,IAAI,SAAS,EAChCA,QACX,CAAC"}
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"}