@effectstream/utils 0.100.13 → 0.100.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effectstream/utils",
3
- "version": "0.100.13",
3
+ "version": "0.100.14",
4
4
  "license": "MIT",
5
5
  "homepage": "https://effectstream.github.io/docs/",
6
6
  "repository": {
@@ -15,7 +15,8 @@
15
15
  ".": "./src/mod.ts",
16
16
  "./node-env": "./src/config.ts",
17
17
  "./runtime": "./src/runtime.ts",
18
- "./runtime-spawn": "./src/runtime-spawn.ts"
18
+ "./runtime-spawn": "./src/runtime-spawn.ts",
19
+ "./fs": "./src/fs.ts"
19
20
  },
20
21
  "dependencies": {
21
22
  "@coderspirit/nominal": "^4.1.1",
package/src/config.ts CHANGED
@@ -155,26 +155,50 @@ const definitions: Record<string, ConfigDefinition> = {
155
155
  MQTT_ENGINE_BROKER_URL: {
156
156
  key: "MQTT_ENGINE_BROKER_URL",
157
157
  type: "string",
158
- defaultValue: "ws://127.0.0.1:8883",
159
- description: "MQTT Engine Broker URL. Example: 'ws://127.0.0.1:8883'",
158
+ defaultValue: "mqtt://127.0.0.1:8883",
159
+ description: "MQTT Engine Broker TCP URL. Example: 'mqtt://127.0.0.1:8883'",
160
160
  },
161
161
  MQTT_ENGINE_BROKER_PORT: {
162
162
  key: "MQTT_ENGINE_BROKER_PORT",
163
163
  type: "number",
164
164
  defaultValue: 8883,
165
- description: "MQTT Engine Broker Port. Example: '8883'",
165
+ description: "MQTT Engine Broker TCP Port. Example: '8883'",
166
+ },
167
+ MQTT_ENGINE_BROKER_WS_URL: {
168
+ key: "MQTT_ENGINE_BROKER_WS_URL",
169
+ type: "string",
170
+ defaultValue: "ws://127.0.0.1:9883",
171
+ description: "MQTT Engine Broker WebSocket URL (for browser clients). Example: 'ws://127.0.0.1:9883'",
172
+ },
173
+ MQTT_ENGINE_BROKER_WS_PORT: {
174
+ key: "MQTT_ENGINE_BROKER_WS_PORT",
175
+ type: "number",
176
+ defaultValue: 9883,
177
+ description: "MQTT Engine Broker WebSocket Port. Example: '9883'",
166
178
  },
167
179
  MQTT_BATCHER_BROKER_URL: {
168
180
  key: "MQTT_BATCHER_BROKER_URL",
169
181
  type: "string",
170
- defaultValue: "ws://127.0.0.1:8884",
171
- description: "MQTT Batcher Broker URL. Example: 'ws://127.0.0.1:8884'",
182
+ defaultValue: "mqtt://127.0.0.1:8884",
183
+ description: "MQTT Batcher Broker TCP URL. Example: 'mqtt://127.0.0.1:8884'",
172
184
  },
173
185
  MQTT_BATCHER_BROKER_PORT: {
174
186
  key: "MQTT_BATCHER_BROKER_PORT",
175
187
  type: "number",
176
188
  defaultValue: 8884,
177
- description: "MQTT Batcher Broker Port. Example: '8884'",
189
+ description: "MQTT Batcher Broker TCP Port. Example: '8884'",
190
+ },
191
+ MQTT_BATCHER_BROKER_WS_URL: {
192
+ key: "MQTT_BATCHER_BROKER_WS_URL",
193
+ type: "string",
194
+ defaultValue: "ws://127.0.0.1:9884",
195
+ description: "MQTT Batcher Broker WebSocket URL (for browser clients). Example: 'ws://127.0.0.1:9884'",
196
+ },
197
+ MQTT_BATCHER_BROKER_WS_PORT: {
198
+ key: "MQTT_BATCHER_BROKER_WS_PORT",
199
+ type: "number",
200
+ defaultValue: 9884,
201
+ description: "MQTT Batcher Broker WebSocket Port. Example: '9884'",
178
202
  },
179
203
  EFFECTSTREAM_API_PORT: {
180
204
  key: "EFFECTSTREAM_API_PORT",
@@ -297,15 +321,27 @@ export class ENV {
297
321
  static get MQTT_ENGINE_BROKER_PORT(): number {
298
322
  return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_PORT);
299
323
  }
324
+ static get MQTT_ENGINE_BROKER_WS_PORT(): number {
325
+ return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_WS_PORT);
326
+ }
300
327
  static get MQTT_BATCHER_BROKER_PORT(): number {
301
328
  return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_PORT);
302
329
  }
330
+ static get MQTT_BATCHER_BROKER_WS_PORT(): number {
331
+ return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_WS_PORT);
332
+ }
303
333
  static get MQTT_ENGINE_BROKER_URL(): string {
304
334
  return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_URL);
305
335
  }
336
+ static get MQTT_ENGINE_BROKER_WS_URL(): string {
337
+ return ENV.getConfig(definitions.MQTT_ENGINE_BROKER_WS_URL);
338
+ }
306
339
  static get MQTT_BATCHER_BROKER_URL(): string {
307
340
  return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_URL);
308
341
  }
342
+ static get MQTT_BATCHER_BROKER_WS_URL(): string {
343
+ return ENV.getConfig(definitions.MQTT_BATCHER_BROKER_WS_URL);
344
+ }
309
345
  static get DB_HOST(): string {
310
346
  return ENV.getConfig(definitions.DB_HOST);
311
347
  }
package/src/fs.ts ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Cross-runtime filesystem primitives.
3
+ *
4
+ * Thin wrappers over `node:fs/promises`, which works identically under Deno,
5
+ * Node, and Bun — no runtime branching. The surface area is intentionally
6
+ * small: only what the codebase actually uses.
7
+ *
8
+ * ## Why this lives in its own entry, not in `runtime.ts`
9
+ *
10
+ * `runtime.ts` is re-exported from the package barrel (`mod.ts`). Anything
11
+ * that imports from `@effectstream/utils` (e.g. the explorer client bundled
12
+ * by Vite) drags the entire re-exported graph along. Keeping fs helpers in
13
+ * `runtime.ts` means any browser build pulls `node:fs/promises`,
14
+ * `node:os`, and `node:path` into its bundle — which Vite rightly rejects.
15
+ *
16
+ * This file is deliberately **not** re-exported from `mod.ts`. Importers
17
+ * must reach for the `@effectstream/utils/fs` subpath explicitly, and
18
+ * client/browser code stays clean.
19
+ */
20
+
21
+ import { mkdir, mkdtemp, readdir, rm, stat, utimes, writeFile } from "node:fs/promises";
22
+ import { tmpdir } from "node:os";
23
+ import { join } from "node:path";
24
+ import { isNotFoundError } from "./runtime.ts";
25
+
26
+ /** Create a unique temp directory and return its absolute path. */
27
+ export async function makeTempDir(opts: { prefix?: string } = {}): Promise<string> {
28
+ return await mkdtemp(join(tmpdir(), opts.prefix ?? "tmp-"));
29
+ }
30
+
31
+ /** Create a directory (and parents) if missing. */
32
+ export async function mkdirRecursive(path: string): Promise<void> {
33
+ await mkdir(path, { recursive: true });
34
+ }
35
+
36
+ /** Write a UTF-8 string to `path`, overwriting any existing file. */
37
+ export async function writeTextFile(path: string, data: string): Promise<void> {
38
+ await writeFile(path, data, "utf8");
39
+ }
40
+
41
+ /** Set access and modification times on `path` (accepts Date or ms). */
42
+ export async function setFileTimes(
43
+ path: string,
44
+ atime: Date | number,
45
+ mtime: Date | number,
46
+ ): Promise<void> {
47
+ await utimes(
48
+ path,
49
+ atime instanceof Date ? atime : new Date(atime),
50
+ mtime instanceof Date ? mtime : new Date(mtime),
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Remove a file or directory. Pass `recursive` to delete non-empty dirs,
56
+ * and `ignoreMissing` to swallow ENOENT.
57
+ */
58
+ export async function remove(
59
+ path: string,
60
+ opts: { recursive?: boolean; ignoreMissing?: boolean } = {},
61
+ ): Promise<void> {
62
+ try {
63
+ await rm(path, { recursive: opts.recursive ?? false, force: false });
64
+ } catch (e) {
65
+ if (opts.ignoreMissing && isNotFoundError(e)) return;
66
+ throw e;
67
+ }
68
+ }
69
+
70
+ export interface DirEntry {
71
+ name: string;
72
+ isFile: boolean;
73
+ isDirectory: boolean;
74
+ }
75
+
76
+ /** List entries in a directory. Throws (with a NotFound-shaped error) if missing. */
77
+ export async function* readDir(path: string): AsyncIterable<DirEntry> {
78
+ const entries = await readdir(path, { withFileTypes: true });
79
+ for (const e of entries) {
80
+ yield { name: e.name, isFile: e.isFile(), isDirectory: e.isDirectory() };
81
+ }
82
+ }
83
+
84
+ /** Stat a file; returns mtime as ms since epoch (0 if unavailable). */
85
+ export async function statMtime(path: string): Promise<number> {
86
+ const s = await stat(path);
87
+ return s.mtimeMs ?? s.mtime?.getTime() ?? 0;
88
+ }
package/src/runtime.ts CHANGED
@@ -87,3 +87,8 @@ export function isNotFoundError(err: unknown): boolean {
87
87
  }
88
88
  return false;
89
89
  }
90
+
91
+ // Filesystem helpers (makeTempDir, readDir, etc.) live in `./fs.ts` under
92
+ // the `@effectstream/utils/fs` subpath export. They intentionally do NOT
93
+ // re-export from this file, because this file is re-exported by the package
94
+ // barrel (`mod.ts`) — dragging `node:fs/promises` into browser bundles.