@vrtmrz/livesync-commonlib 0.1.0-rc.0 → 0.1.0-rc.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.
package/README.md CHANGED
@@ -36,6 +36,20 @@ await storage.write('notes/example.md', '# Example');
36
36
 
37
37
  See [the platform storage contract](docs/platform-storage.md) for path, ownership, and permission details.
38
38
 
39
+ ## Standard input and output
40
+
41
+ CLI hosts can inject the platform-neutral `StandardIo` contract from the context entry. The Node entry supplies the concrete stream adapter. This keeps command input and protocol output testable without treating logging or process lifecycle as standard I/O.
42
+
43
+ ```ts
44
+ import type { StandardIo } from '@vrtmrz/livesync-commonlib/context';
45
+ import { createNodeStandardIo } from '@vrtmrz/livesync-commonlib/node';
46
+
47
+ const standardIo: StandardIo = createNodeStandardIo();
48
+ standardIo.writeStdout('ready\n');
49
+ ```
50
+
51
+ See [the standard-I/O contract](docs/platform-standard-io.md) for host composition and test-double examples.
52
+
39
53
  ## API status
40
54
 
41
55
  The package is currently an infrastructure and compatibility boundary. `DirectFileManipulator` is useful for existing integrations, but its enumeration, watch ownership, failure, conflict, concurrency, and disposal semantics are not yet a stable high-level SDK contract.
package/dist/context.d.ts CHANGED
@@ -6,3 +6,4 @@
6
6
  export { ServiceContext, createServiceContext, type ServiceContextContract, type ServiceContextOptions, } from "./services/base/ServiceBase.js";
7
7
  export { createLiveSyncEventHub, type LiveSyncEventHub } from "./hub/hub.js";
8
8
  export { passthroughMessageTranslator, type MessageTranslator, type TranslationParameters, } from "./services/base/MessageTranslator.js";
9
+ export type { StandardIo, StandardIoChunk } from "./platform/standardIo.js";
@@ -21,3 +21,4 @@ export declare const builtinModules: readonly string[];
21
21
  /** Returns whether a module specifier refers to a Node built-in. */
22
22
  export declare const isBuiltin: typeof nodeIsBuiltin;
23
23
  export { NodeStorageAdapter, createNodeStorage, validateStoragePath, type CreateNodeStorageOptions, type NodeStorageStat, } from "./storage.js";
24
+ export { createNodeStandardIo, type CreateNodeStandardIoOptions, type NodeStandardInput, type NodeStandardOutput, } from "./standardIo.js";
@@ -17,9 +17,13 @@ import {
17
17
  createNodeStorage,
18
18
  validateStoragePath
19
19
  } from "./storage.js";
20
+ import {
21
+ createNodeStandardIo
22
+ } from "./standardIo.js";
20
23
  export {
21
24
  NodeStorageAdapter,
22
25
  builtinModules,
26
+ createNodeStandardIo,
23
27
  createNodeStorage,
24
28
  fileURLToPath,
25
29
  fs,
@@ -0,0 +1,24 @@
1
+ import type { StandardIo, StandardIoChunk } from "../standardIo.js";
2
+ /** Minimal readable stream shape accepted by the Node standard-I/O adapter. */
3
+ export type NodeStandardInput = AsyncIterable<unknown> & NodeJS.ReadableStream;
4
+ /** Minimal writable stream shape accepted by the Node standard-I/O adapter. */
5
+ export interface NodeStandardOutput extends NodeJS.WritableStream {
6
+ write(chunk: StandardIoChunk): boolean;
7
+ }
8
+ /** Streams used by {@link createNodeStandardIo}. */
9
+ export interface CreateNodeStandardIoOptions {
10
+ /** Defaults to `process.stdin`. */
11
+ stdin?: NodeStandardInput;
12
+ /** Defaults to `process.stdout`. */
13
+ stdout?: NodeStandardOutput;
14
+ /** Defaults to `process.stderr`. */
15
+ stderr?: NodeStandardOutput;
16
+ }
17
+ /**
18
+ * Bind the host-neutral standard-I/O contract to Node streams.
19
+ *
20
+ * Supplying streams is useful for embedded command-line hosts and tests. The
21
+ * caller owns stream lifecycle; this adapter only closes the temporary
22
+ * readline interface created by {@link StandardIo.prompt}.
23
+ */
24
+ export declare function createNodeStandardIo(options?: CreateNodeStandardIoOptions): StandardIo;
@@ -0,0 +1,39 @@
1
+ import * as nodeReadlinePromises from "node:readline/promises";
2
+ function createNodeStandardIo(options = {}) {
3
+ const stdin = options.stdin ?? process.stdin;
4
+ const stdout = options.stdout ?? process.stdout;
5
+ const stderr = options.stderr ?? process.stderr;
6
+ return {
7
+ async readStdin() {
8
+ const decoder = new TextDecoder();
9
+ let content = "";
10
+ for await (const chunk of stdin) {
11
+ if (typeof chunk === "string") {
12
+ content += chunk;
13
+ } else if (chunk instanceof Uint8Array) {
14
+ content += decoder.decode(chunk, { stream: true });
15
+ } else {
16
+ throw new TypeError("Standard input yielded a value which is neither text nor binary data.");
17
+ }
18
+ }
19
+ return content + decoder.decode();
20
+ },
21
+ async prompt(question) {
22
+ const readline = nodeReadlinePromises.createInterface({ input: stdin, output: stdout });
23
+ try {
24
+ return await readline.question(question);
25
+ } finally {
26
+ readline.close();
27
+ }
28
+ },
29
+ writeStdout(chunk) {
30
+ stdout.write(chunk);
31
+ },
32
+ writeStderr(chunk) {
33
+ stderr.write(chunk);
34
+ }
35
+ };
36
+ }
37
+ export {
38
+ createNodeStandardIo
39
+ };
@@ -0,0 +1,19 @@
1
+ /** A chunk written to standard output or standard error. */
2
+ export type StandardIoChunk = string | Uint8Array;
3
+ /**
4
+ * Host-provided standard input and output for a command-line composition.
5
+ *
6
+ * The contract deliberately excludes process lifecycle, logging policy, and
7
+ * terminal capability detection. Hosts own those concerns separately. None of
8
+ * the write operations add a newline implicitly.
9
+ */
10
+ export interface StandardIo {
11
+ /** Read standard input to completion and decode it as UTF-8 text. */
12
+ readStdin(): Promise<string>;
13
+ /** Ask one line-oriented question and return the entered text. */
14
+ prompt(question: string): Promise<string>;
15
+ /** Write a text or binary chunk to standard output. */
16
+ writeStdout(chunk: StandardIoChunk): void;
17
+ /** Write a text or binary chunk to standard error. */
18
+ writeStderr(chunk: StandardIoChunk): void;
19
+ }
File without changes
@@ -18,7 +18,8 @@ npm run test:package
18
18
  `test:contracts` runs the host-neutral result contracts which are intended to be reusable while implementations move:
19
19
 
20
20
  - `test:contract:context` verifies event delivery, default instance isolation, translation results, and host extension of `ServiceContextContract`; and
21
- - `test:contract:platform-storage` runs one result table against Node storage and browser File System Access storage, including missing paths, text and binary round trips, append, listing, removal, root handling, and traversal rejection.
21
+ - `test:contract:platform-storage` runs one result table against Node storage and browser File System Access storage, including missing paths, text and binary round trips, append, listing, removal, root handling, and traversal rejection; and
22
+ - `test:contract:standard-io` verifies the injectable contract, UTF-8 decoding across chunks, text and binary output, and line-oriented prompting through injected Node streams.
22
23
 
23
24
  These scripts are deliberately available independently of CI. Add a focused result contract before moving another platform API; do not infer compatibility from matching TypeScript shapes alone. Platform-specific behaviour, such as timestamp fidelity, must remain documented outside the shared result set.
24
25
 
@@ -0,0 +1,44 @@
1
+ # Standard input and output
2
+
3
+ Commonlib defines a narrow `StandardIo` contract for command-line hosts. The contract covers standard input, line-oriented prompting, standard output, and standard error. It does not own process arguments, exit codes, signals, logging levels, or log persistence.
4
+
5
+ ## Host composition
6
+
7
+ The host chooses and constructs the implementation, then places it on its host-specific Context or passes it to the command composition which owns it. The base `ServiceContext` does not require standard I/O because Obsidian, browser, and headless service compositions do not all have terminal streams.
8
+
9
+ ```ts
10
+ import type { StandardIo } from '@vrtmrz/livesync-commonlib/context';
11
+ import { createNodeStandardIo } from '@vrtmrz/livesync-commonlib/node';
12
+
13
+ class CliContext {
14
+ constructor(readonly standardIo: StandardIo) {}
15
+ }
16
+
17
+ const context = new CliContext(createNodeStandardIo());
18
+ ```
19
+
20
+ `createNodeStandardIo()` binds to `process.stdin`, `process.stdout`, and `process.stderr` by default. An embedding host may supply alternative Node streams. The host remains responsible for those streams and their lifecycle.
21
+
22
+ ## Output contract
23
+
24
+ `writeStdout()` and `writeStderr()` accept text or `Uint8Array` chunks and do not add a newline. Commands must add delimiters required by their own text protocol. Binary command output must use `writeStdout()` directly without conversion through a logger.
25
+
26
+ Diagnostic logging remains a separate capability. A host can render selected logs to standard error, but Commonlib does not make a Logger part of `StandardIo` and does not interpret log levels in this adapter.
27
+
28
+ ## Tests and embedded hosts
29
+
30
+ Consumers can inject a small memory implementation without replacing process globals:
31
+
32
+ ```ts
33
+ import type { StandardIo, StandardIoChunk } from '@vrtmrz/livesync-commonlib/context';
34
+
35
+ const stdout: StandardIoChunk[] = [];
36
+ const io: StandardIo = {
37
+ readStdin: async () => 'input',
38
+ prompt: async () => 'answer',
39
+ writeStdout: (chunk) => stdout.push(chunk),
40
+ writeStderr: () => undefined,
41
+ };
42
+ ```
43
+
44
+ This boundary lets a command test assert exact protocol bytes, prompts, and errors while the real Node adapter is verified separately against injected streams.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vrtmrz/livesync-commonlib",
3
- "version": "0.1.0-rc.0",
3
+ "version": "0.1.0-rc.1",
4
4
  "description": "Shared data, storage, and replication primitives for Self-hosted LiveSync clients.",
5
5
  "type": "module",
6
6
  "license": "MIT",