@alloy-js/core 0.19.0-dev.2 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/components/AppendFile.d.ts +90 -0
  3. package/dist/src/components/AppendFile.d.ts.map +1 -0
  4. package/dist/src/components/AppendFile.js +226 -0
  5. package/dist/src/components/CopyFile.d.ts +12 -0
  6. package/dist/src/components/CopyFile.d.ts.map +1 -0
  7. package/dist/src/components/CopyFile.js +15 -0
  8. package/dist/src/components/TemplateFile.d.ts +84 -0
  9. package/dist/src/components/TemplateFile.d.ts.map +1 -0
  10. package/dist/src/components/TemplateFile.js +133 -0
  11. package/dist/src/components/UpdateFile.d.ts +34 -0
  12. package/dist/src/components/UpdateFile.d.ts.map +1 -0
  13. package/dist/src/components/UpdateFile.js +66 -0
  14. package/dist/src/components/index.d.ts +4 -0
  15. package/dist/src/components/index.d.ts.map +1 -1
  16. package/dist/src/components/index.js +4 -0
  17. package/dist/src/components/stc/index.d.ts +4 -0
  18. package/dist/src/components/stc/index.d.ts.map +1 -1
  19. package/dist/src/components/stc/index.js +4 -0
  20. package/dist/src/context/source-directory.d.ts +3 -3
  21. package/dist/src/context/source-directory.d.ts.map +1 -1
  22. package/dist/src/context/source-file.d.ts +4 -0
  23. package/dist/src/context/source-file.d.ts.map +1 -1
  24. package/dist/src/debug.d.ts.map +1 -1
  25. package/dist/src/debug.js +4 -1
  26. package/dist/src/host/alloy-host.browser.d.ts +11 -0
  27. package/dist/src/host/alloy-host.browser.d.ts.map +1 -0
  28. package/dist/src/host/alloy-host.browser.js +31 -0
  29. package/dist/src/host/alloy-host.d.ts +11 -0
  30. package/dist/src/host/alloy-host.d.ts.map +1 -0
  31. package/dist/src/host/alloy-host.js +143 -0
  32. package/dist/src/host/interface.d.ts +144 -0
  33. package/dist/src/host/interface.d.ts.map +1 -0
  34. package/dist/src/host/interface.js +1 -0
  35. package/dist/src/index.browser.d.ts +1 -1
  36. package/dist/src/index.browser.d.ts.map +1 -1
  37. package/dist/src/index.browser.js +2 -2
  38. package/dist/src/reactivity.js +2 -2
  39. package/dist/src/render.d.ts +10 -2
  40. package/dist/src/render.d.ts.map +1 -1
  41. package/dist/src/render.js +20 -1
  42. package/dist/src/resource.d.ts +80 -0
  43. package/dist/src/resource.d.ts.map +1 -0
  44. package/dist/src/resource.js +118 -0
  45. package/dist/src/scheduler.d.ts +6 -0
  46. package/dist/src/scheduler.d.ts.map +1 -1
  47. package/dist/src/scheduler.js +36 -0
  48. package/dist/src/write-output.d.ts +1 -1
  49. package/dist/src/write-output.d.ts.map +1 -1
  50. package/dist/src/write-output.js +40 -21
  51. package/dist/test/components/append-file.test.d.ts +2 -0
  52. package/dist/test/components/append-file.test.d.ts.map +1 -0
  53. package/dist/test/components/append-file.test.js +281 -0
  54. package/dist/test/components/copy-file.test.d.ts +2 -0
  55. package/dist/test/components/copy-file.test.d.ts.map +1 -0
  56. package/dist/test/components/copy-file.test.js +94 -0
  57. package/dist/test/components/source-file.test.d.ts.map +1 -1
  58. package/dist/test/components/template-file.test.d.ts +2 -0
  59. package/dist/test/components/template-file.test.d.ts.map +1 -0
  60. package/dist/test/components/template-file.test.js +133 -0
  61. package/dist/test/components/update-file.test.d.ts +2 -0
  62. package/dist/test/components/update-file.test.d.ts.map +1 -0
  63. package/dist/test/components/update-file.test.js +169 -0
  64. package/dist/test/rendering/formatting.test.d.ts.map +1 -1
  65. package/dist/testing/extend-expect.js +60 -54
  66. package/dist/tsconfig.tsbuildinfo +1 -1
  67. package/package.json +6 -6
  68. package/src/components/AppendFile.tsx +294 -0
  69. package/src/components/CopyFile.tsx +29 -0
  70. package/src/components/TemplateFile.tsx +193 -0
  71. package/src/components/UpdateFile.tsx +86 -0
  72. package/src/components/index.tsx +4 -0
  73. package/src/components/stc/index.ts +4 -0
  74. package/src/context/source-directory.ts +5 -3
  75. package/src/context/source-file.ts +5 -0
  76. package/src/debug.ts +4 -1
  77. package/src/host/alloy-host.browser.ts +56 -0
  78. package/src/host/alloy-host.ts +160 -0
  79. package/src/host/interface.ts +153 -0
  80. package/src/index.browser.ts +1 -1
  81. package/src/reactivity.ts +2 -2
  82. package/src/render.ts +44 -5
  83. package/src/resource.ts +152 -0
  84. package/src/scheduler.ts +39 -0
  85. package/src/write-output.ts +49 -19
  86. package/temp/api.json +2009 -546
  87. package/test/components/append-file.test.tsx +275 -0
  88. package/test/components/copy-file.test.tsx +98 -0
  89. package/test/components/source-file.test.tsx +5 -2
  90. package/test/components/template-file.test.tsx +127 -0
  91. package/test/components/update-file.test.tsx +214 -0
  92. package/test/rendering/formatting.test.tsx +9 -3
  93. package/testing/extend-expect.ts +74 -58
  94. package/testing/vitest.d.ts +4 -0
  95. package/dist/src/write-output.browser.d.ts +0 -2
  96. package/dist/src/write-output.browser.d.ts.map +0 -1
  97. package/dist/src/write-output.browser.js +0 -4
  98. package/src/write-output.browser.ts +0 -4
package/src/scheduler.ts CHANGED
@@ -5,6 +5,7 @@ export interface QueueJob {
5
5
  }
6
6
  const immediateQueue = new Set<QueueJob>();
7
7
  const queue = new Set<QueueJob>();
8
+ const pendingPromises = new Set<Promise<any>>();
8
9
 
9
10
  export function scheduler(
10
11
  jobGetter: () => ReactiveEffectRunner,
@@ -25,11 +26,49 @@ export function queueJob(job: QueueJob, immediate = false) {
25
26
  }
26
27
  }
27
28
 
29
+ /**
30
+ * Register a promise that the scheduler should wait for during flushJobs.
31
+ * This is used by async resources to ensure the scheduler waits for their completion.
32
+ */
33
+ export function trackPromise(promise: Promise<any>) {
34
+ pendingPromises.add(promise);
35
+ void promise.finally(() => {
36
+ pendingPromises.delete(promise);
37
+ });
38
+ }
39
+
28
40
  export function flushJobs() {
41
+ // First, run all synchronous jobs
29
42
  let job;
30
43
  while ((job = takeJob()) !== null) {
31
44
  job();
32
45
  }
46
+
47
+ // If there are no pending promises, we're done
48
+ if (pendingPromises.size > 0) {
49
+ throw new Error(
50
+ "Asynchronous jobs were found but render was called synchronously. Use `asyncRender` instead.",
51
+ );
52
+ }
53
+ }
54
+
55
+ export async function flushJobsAsync() {
56
+ // Keep running jobs until both the queues are empty and all promises are resolved
57
+ while (true) {
58
+ // First, run all synchronous jobs
59
+ let job;
60
+ while ((job = takeJob()) !== null) {
61
+ job();
62
+ }
63
+
64
+ // If there are no pending promises, we're done
65
+ if (pendingPromises.size === 0) {
66
+ break;
67
+ }
68
+
69
+ // Wait for all current promises to complete
70
+ await Promise.allSettled(Array.from(pendingPromises));
71
+ }
33
72
  }
34
73
 
35
74
  function takeJob() {
@@ -1,33 +1,63 @@
1
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
- import { relative, resolve } from "pathe";
1
+ import { dirname, relative, resolve } from "pathe";
2
+ import { AlloyHost } from "./host/alloy-host.js";
3
3
  import { OutputDirectory } from "./render.js";
4
4
  import { traverseOutput } from "./utils.js";
5
5
  /**
6
6
  * Write the output from {@link render} to the file system.
7
7
  *
8
8
  */
9
- export function writeOutput(output: OutputDirectory, basePath: string = "") {
9
+ export async function writeOutput(
10
+ output: OutputDirectory,
11
+ basePath: string = "",
12
+ ) {
13
+ const ops: Promise<void>[] = [];
14
+
10
15
  traverseOutput(output, {
11
16
  visitDirectory(directory) {
12
- const path = resolve(basePath, directory.path);
13
- if (existsSync(path)) {
14
- return;
15
- }
16
- // eslint-disable-next-line no-console
17
- console.log("create", relative(process.cwd(), path));
18
- mkdirSync(path, { recursive: true });
17
+ ops.push(
18
+ (async () => {
19
+ const path = resolve(basePath, directory.path);
20
+ if (await AlloyHost.exists(path)) {
21
+ return;
22
+ }
23
+ // eslint-disable-next-line no-console
24
+ console.log("create", relative(process.cwd(), path));
25
+ await AlloyHost.mkdir(path);
26
+ })(),
27
+ );
19
28
  },
20
29
  visitFile(file) {
21
- const path = resolve(basePath, file.path);
22
- if (existsSync(path)) {
23
- // eslint-disable-next-line no-console
24
- console.log("overwrite", relative(process.cwd(), path));
25
- } else {
26
- // eslint-disable-next-line no-console
27
- console.log("create", relative(process.cwd(), path));
28
- }
30
+ ops.push(
31
+ (async () => {
32
+ if ("contents" in file) {
33
+ const path = resolve(basePath, file.path);
34
+ if (await AlloyHost.exists(path)) {
35
+ // eslint-disable-next-line no-console
36
+ console.log("overwrite", relative(process.cwd(), path));
37
+ } else {
38
+ // eslint-disable-next-line no-console
39
+ console.log("create", relative(process.cwd(), path));
40
+ }
29
41
 
30
- writeFileSync(path, file.contents);
42
+ await AlloyHost.write(path, file.contents);
43
+ } else {
44
+ // copy file
45
+ const source = resolve(basePath, file.sourcePath);
46
+ const target = resolve(basePath, file.path);
47
+ if (await AlloyHost.exists(target)) {
48
+ // eslint-disable-next-line no-console
49
+ console.log("copy over", relative(process.cwd(), target));
50
+ } else {
51
+ // eslint-disable-next-line no-console
52
+ console.log("copy", relative(process.cwd(), target));
53
+ }
54
+ await AlloyHost.mkdir(dirname(target));
55
+ await AlloyHost.write(target, AlloyHost.read(source).stream());
56
+ }
57
+ })(),
58
+ );
31
59
  },
32
60
  });
61
+
62
+ return Promise.all(ops);
33
63
  }