@simplysm/core-node 13.0.100 → 14.0.1

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 (41) hide show
  1. package/dist/features/fs-watcher.d.ts +21 -21
  2. package/dist/features/fs-watcher.d.ts.map +1 -1
  3. package/dist/features/fs-watcher.js +176 -114
  4. package/dist/features/fs-watcher.js.map +1 -6
  5. package/dist/index.js +6 -7
  6. package/dist/index.js.map +1 -6
  7. package/dist/utils/fs.d.ts +96 -96
  8. package/dist/utils/fs.d.ts.map +1 -1
  9. package/dist/utils/fs.js +437 -272
  10. package/dist/utils/fs.js.map +1 -6
  11. package/dist/utils/path.d.ts +22 -22
  12. package/dist/utils/path.js +103 -45
  13. package/dist/utils/path.js.map +1 -6
  14. package/dist/worker/create-worker.d.ts +3 -3
  15. package/dist/worker/create-worker.js +106 -81
  16. package/dist/worker/create-worker.js.map +1 -6
  17. package/dist/worker/types.d.ts +14 -14
  18. package/dist/worker/types.js +4 -1
  19. package/dist/worker/types.js.map +1 -6
  20. package/dist/worker/worker.d.ts +5 -5
  21. package/dist/worker/worker.js +168 -132
  22. package/dist/worker/worker.js.map +1 -6
  23. package/lib/worker-dev-proxy.js +15 -0
  24. package/package.json +8 -6
  25. package/src/features/fs-watcher.ts +53 -42
  26. package/src/index.ts +3 -3
  27. package/src/utils/fs.ts +111 -120
  28. package/src/utils/path.ts +26 -26
  29. package/src/worker/create-worker.ts +10 -10
  30. package/src/worker/types.ts +14 -14
  31. package/src/worker/worker.ts +29 -29
  32. package/README.md +0 -112
  33. package/docs/features.md +0 -91
  34. package/docs/fs.md +0 -309
  35. package/docs/path.md +0 -120
  36. package/docs/worker.md +0 -168
  37. package/tests/utils/fs-watcher.spec.ts +0 -286
  38. package/tests/utils/fs.spec.ts +0 -705
  39. package/tests/utils/path.spec.ts +0 -179
  40. package/tests/worker/fixtures/test-worker.ts +0 -35
  41. package/tests/worker/sd-worker.spec.ts +0 -174
@@ -1,286 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import path from "path";
3
- import fs from "fs";
4
- import os from "os";
5
- import { FsWatcher } from "../../src/features/fs-watcher";
6
-
7
- describe("SdFsWatcher", () => {
8
- const testDir = path.join(os.tmpdir(), "fs-watcher-test-" + Date.now());
9
- let watcher: FsWatcher | undefined;
10
-
11
- beforeEach(() => {
12
- fs.mkdirSync(testDir, { recursive: true });
13
- });
14
-
15
- afterEach(async () => {
16
- if (watcher != null) {
17
- await watcher.close();
18
- watcher = undefined;
19
- }
20
- fs.rmSync(testDir, { recursive: true, force: true });
21
- });
22
-
23
- //#region watch
24
-
25
- describe("watch", () => {
26
- it("starts watching files", async () => {
27
- watcher = await FsWatcher.watch([path.join(testDir, "**/*")]);
28
- expect(watcher).toBeDefined();
29
- });
30
-
31
- });
32
-
33
- //#endregion
34
-
35
- //#region close
36
-
37
- describe("close", () => {
38
- it("closes the watcher", async () => {
39
- watcher = await FsWatcher.watch([path.join(testDir, "**/*")]);
40
-
41
- // Test passes if close() completes without error
42
- await expect(watcher.close()).resolves.toBeUndefined();
43
-
44
- // Release watcher reference after closing
45
- watcher = undefined;
46
- });
47
- });
48
-
49
- //#endregion
50
-
51
- //#region chaining
52
-
53
- describe("onChange", () => {
54
- it("supports onChange method chaining", async () => {
55
- watcher = await FsWatcher.watch([path.join(testDir, "**/*")]);
56
-
57
- const fn = vi.fn();
58
- const result = watcher.onChange({ delay: 100 }, fn);
59
-
60
- expect(result).toBe(watcher);
61
- });
62
- });
63
-
64
- //#endregion
65
-
66
- //#region Glob Pattern Filtering
67
-
68
- describe("glob pattern filtering", () => {
69
- const DELAY = 300;
70
-
71
- const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
72
-
73
- const waitForChanges = (
74
- watcherInstance: FsWatcher,
75
- delay: number,
76
- ): Promise<Array<{ event: string; path: string }>> => {
77
- return new Promise((resolve) => {
78
- watcherInstance.onChange({ delay }, (changeInfos) => {
79
- resolve(changeInfos.map((c) => ({ event: c.event, path: c.path })));
80
- });
81
- });
82
- };
83
-
84
- it("receives events only for files matching glob pattern", async () => {
85
- // Glob pattern that watches only .txt files
86
- const globPattern = path.join(testDir, "**/*.txt");
87
-
88
- watcher = await FsWatcher.watch([globPattern]);
89
-
90
- const changesPromise = waitForChanges(watcher, DELAY);
91
-
92
- // Create .txt file (matches)
93
- fs.writeFileSync(path.join(testDir, "matched.txt"), "hello");
94
-
95
- // Create .json file (does not match)
96
- await wait(50);
97
- fs.writeFileSync(path.join(testDir, "ignored.json"), "{}");
98
-
99
- const changes = await changesPromise;
100
-
101
- // Should only receive events for .txt file
102
- expect(changes.length).toBe(1);
103
- expect(changes[0].path).toContain("matched.txt");
104
- expect(changes[0].event).toBe("add");
105
- });
106
- });
107
-
108
- //#endregion
109
-
110
- //#region Event Merging
111
-
112
- describe("event merging", () => {
113
- const DELAY = 300;
114
-
115
- /**
116
- * Helper function to wait for specified time.
117
- */
118
- const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
119
-
120
- /**
121
- * Helper function to wait until event callback is called.
122
- */
123
- const waitForChanges = (
124
- watcherInstance: FsWatcher,
125
- delay: number,
126
- ): Promise<Array<{ event: string; path: string }>> => {
127
- return new Promise((resolve) => {
128
- watcherInstance.onChange({ delay }, (changeInfos) => {
129
- resolve(changeInfos.map((c) => ({ event: c.event, path: c.path })));
130
- });
131
- });
132
- };
133
-
134
- it("returns only add event when file is added then modified", async () => {
135
- const testFile = path.join(testDir, "test-add-change.txt");
136
-
137
- watcher = await FsWatcher.watch([testDir]);
138
-
139
- const changesPromise = waitForChanges(watcher, DELAY);
140
-
141
- // Add file
142
- fs.writeFileSync(testFile, "initial");
143
-
144
- // Modify file with short interval (must occur within delay)
145
- await wait(50);
146
- fs.writeFileSync(testFile, "modified");
147
-
148
- // Wait for event callback
149
- const changes = await changesPromise;
150
-
151
- // add → change should be merged to add
152
- expect(changes.length).toBe(1);
153
- expect(changes[0].event).toBe("add");
154
- });
155
-
156
- it("produces no events or no changes when file is added then deleted", async () => {
157
- const testFile = path.join(testDir, "test-add-unlink.txt");
158
-
159
- watcher = await FsWatcher.watch([testDir]);
160
-
161
- const changes: Array<{ event: string; path: string }> = [];
162
- let resolved = false;
163
-
164
- const changesPromise = new Promise<void>((resolve) => {
165
- watcher!.onChange({ delay: DELAY }, (changeInfos) => {
166
- changes.push(...changeInfos.map((c) => ({ event: c.event, path: c.path })));
167
- if (!resolved) {
168
- resolved = true;
169
- resolve();
170
- }
171
- });
172
- });
173
-
174
- // Add file
175
- fs.writeFileSync(testFile, "content");
176
-
177
- // Delete file with short interval
178
- await wait(50);
179
- fs.unlinkSync(testFile);
180
-
181
- // Wait with timeout (event may not occur)
182
- await Promise.race([changesPromise, wait(DELAY + 200)]);
183
-
184
- // add → unlink merged, no events
185
- expect(changes.length).toBe(0);
186
- });
187
-
188
- it("produces no events or no changes when directory is added then deleted", async () => {
189
- const testSubDir = path.join(testDir, "test-addDir-unlinkDir");
190
-
191
- watcher = await FsWatcher.watch([testDir]);
192
-
193
- const changes: Array<{ event: string; path: string }> = [];
194
- let resolved = false;
195
-
196
- const changesPromise = new Promise<void>((resolve) => {
197
- watcher!.onChange({ delay: DELAY }, (changeInfos) => {
198
- changes.push(...changeInfos.map((c) => ({ event: c.event, path: c.path })));
199
- if (!resolved) {
200
- resolved = true;
201
- resolve();
202
- }
203
- });
204
- });
205
-
206
- // Add directory
207
- fs.mkdirSync(testSubDir);
208
-
209
- // Delete directory with short interval
210
- await wait(50);
211
- fs.rmdirSync(testSubDir);
212
-
213
- // Wait with timeout (event may not occur)
214
- await Promise.race([changesPromise, wait(DELAY + 200)]);
215
-
216
- // addDir → unlinkDir merged, no events
217
- expect(changes.length).toBe(0);
218
- });
219
-
220
- it("merges to add event when file is deleted then recreated", async () => {
221
- const testFile = path.join(testDir, "test-unlink-add.txt");
222
-
223
- // Pre-create file
224
- fs.writeFileSync(testFile, "initial");
225
-
226
- watcher = await FsWatcher.watch([testDir]);
227
-
228
- const changesPromise = waitForChanges(watcher, DELAY);
229
-
230
- // Delete file
231
- fs.unlinkSync(testFile);
232
-
233
- // Recreate file with short interval (must occur within delay)
234
- await wait(50);
235
- fs.writeFileSync(testFile, "recreated");
236
-
237
- // Wait for event callback
238
- const changes = await changesPromise;
239
-
240
- // unlink → add/change should be merged to add (overwritten by later event)
241
- // Depending on environment, chokidar may only emit change without unlink (WSL2, etc)
242
- expect(changes.length).toBe(1);
243
- expect(["add", "change"]).toContain(changes[0].event);
244
- });
245
-
246
- it("correctly merges events when multiple files are modified", async () => {
247
- const file1 = path.join(testDir, "file1.txt");
248
- const file2 = path.join(testDir, "file2.txt");
249
- const file3 = path.join(testDir, "file3.txt");
250
-
251
- // Pre-create file3 (to trigger change event)
252
- fs.writeFileSync(file3, "existing");
253
-
254
- watcher = await FsWatcher.watch([testDir]);
255
-
256
- const changesPromise = waitForChanges(watcher, DELAY);
257
-
258
- // file1: only add
259
- fs.writeFileSync(file1, "content1");
260
-
261
- // file2: add then delete (merged and removed)
262
- await wait(50);
263
- fs.writeFileSync(file2, "content2");
264
- await wait(50);
265
- fs.unlinkSync(file2);
266
-
267
- // file3: modify
268
- await wait(50);
269
- fs.writeFileSync(file3, "modified");
270
-
271
- // Wait for event callback
272
- const changes = await changesPromise;
273
-
274
- // file1: add, file2: removed by merge, file3: change
275
- expect(changes.length).toBe(2);
276
-
277
- const file1Change = changes.find((c) => c.path.endsWith("file1.txt"));
278
- const file3Change = changes.find((c) => c.path.endsWith("file3.txt"));
279
-
280
- expect(file1Change?.event).toBe("add");
281
- expect(file3Change?.event).toBe("change");
282
- });
283
- });
284
-
285
- //#endregion
286
- });