@webinson/peer-core 0.0.0-stage → 0.1.894
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/LICENSE +21 -0
- package/README.md +16 -2
- package/dist/AcpMcpStdioBridge-ZWAIz2dT.mjs +233 -0
- package/dist/AcpMcpStdioBridge-up0MRqDk.mjs +3 -0
- package/dist/Clock-B88OfuDl.mjs +185 -0
- package/dist/Effect-DXlc4A9S.mjs +22365 -0
- package/dist/HostProcess-SbwG-qzE.mjs +34 -0
- package/dist/McpHttpServer-BMHEDUFV.mjs +336090 -0
- package/dist/McpHttpServer-ClrT5GD2.mjs +3 -0
- package/dist/Schema-Eq619wkO.mjs +72051 -0
- package/dist/bin.mjs +71 -0
- package/dist/binCli-BRnHIlUQ.mjs +53933 -0
- package/dist/claude-history-worker.mjs +10 -0
- package/dist/claudeHistoryWorker-qaiupgMM.mjs +21 -0
- package/dist/consoleStdin-DO-vIhyg.mjs +3 -0
- package/dist/consoleStdin-DgJxSOye.mjs +68 -0
- package/dist/mcpResponsePayloads-Be_jYC4_.mjs +9897 -0
- package/dist/outboundHttp-DUt9NMiY.mjs +31 -0
- package/dist/rolldown-runtime-1CwlsFOK.mjs +37 -0
- package/package.json +34 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 T3 Tools Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @webinson/peer-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Peer's coordination for coding agents on a computer without the Peer app: the `peer` command.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm i -g @webinson/peer-core # or: npx @webinson/peer-core core status
|
|
7
|
+
peer core login you@company.com # a code is mailed by your Peer Hub
|
|
8
|
+
peer core share ~/code/project # the folder needs a git remote
|
|
9
|
+
peer core connect cursor # Cursor, VS Code, Windsurf, Gemini CLI, OpenCode, Zed, Copilot CLI, Kiro
|
|
10
|
+
peer core hooks install # Claude Code (and Codex with --codex)
|
|
11
|
+
peer core serve --detach # or let the editor start it on demand
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`peer core status` says who runs Peer here; `peer core stop` stops Peer Core. The Peer desktop app,
|
|
15
|
+
when it starts, takes coordination over. Any other `peer <command>` goes to the running Peer.
|
|
16
|
+
|
|
17
|
+
Version 0.1.894 of Peer Local (https://github.com/SemanS/peer-app, branch `peer`), based on T3 Code.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $t as runPromise, Cn as tryPromise, I as fail, Mn as void_, f as asVoid, g as catchCause, mn as sync, o as andThen, st as gen, tt as forkChild, va as squash } from "./Effect-DXlc4A9S.mjs";
|
|
4
|
+
import { Bn as await_, O as fromAsyncIterable, lt as runCollect, n as responsePayloads, pt as runForEach, t as discardResponseBody, zn as awaitAll } from "./mcpResponsePayloads-Be_jYC4_.mjs";
|
|
5
|
+
import * as NodeReadline from "node:readline";
|
|
6
|
+
//#region src/mcp/AcpMcpStdioBridge.ts
|
|
7
|
+
/**
|
|
8
|
+
* ACP agents must support stdio MCP servers, while optional http/sse support is
|
|
9
|
+
* unevenly implemented.
|
|
10
|
+
*/
|
|
11
|
+
var AcpMcpBridgeError = class extends Error {
|
|
12
|
+
_tag = "AcpMcpBridgeError";
|
|
13
|
+
};
|
|
14
|
+
const bridgeError = (cause) => cause instanceof AcpMcpBridgeError ? cause : new AcpMcpBridgeError(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
15
|
+
const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
16
|
+
function asEnvelope(value) {
|
|
17
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
18
|
+
}
|
|
19
|
+
function protocolVersionOf(entry) {
|
|
20
|
+
const result = asEnvelope(entry)?.result;
|
|
21
|
+
const version = typeof result === "object" && result !== null ? result.protocolVersion : void 0;
|
|
22
|
+
return typeof version === "string" && version.length > 0 ? version : null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* This is the terminal fallback for ACP agents that accept `mcpServers` in
|
|
26
|
+
* `session/new` but fail to expose those tools to their model. Compliant ACP
|
|
27
|
+
* agents continue to use the stdio bridge above.
|
|
28
|
+
*/
|
|
29
|
+
function callAcpMcpTool(options) {
|
|
30
|
+
const fetchImplementation = options.fetchImplementation ?? fetch;
|
|
31
|
+
return gen(function* () {
|
|
32
|
+
let sessionId = null;
|
|
33
|
+
let protocolVersion = null;
|
|
34
|
+
const send = (message) => gen(function* () {
|
|
35
|
+
const response = yield* tryPromise({
|
|
36
|
+
try: () => fetchImplementation(options.endpoint, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: {
|
|
39
|
+
"content-type": "application/json",
|
|
40
|
+
accept: "application/json, text/event-stream",
|
|
41
|
+
authorization: options.authorization,
|
|
42
|
+
...sessionId === null ? {} : { "mcp-session-id": sessionId },
|
|
43
|
+
...protocolVersion === null ? {} : { "mcp-protocol-version": protocolVersion }
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify(message)
|
|
46
|
+
}),
|
|
47
|
+
catch: bridgeError
|
|
48
|
+
});
|
|
49
|
+
sessionId = response.headers.get("mcp-session-id") ?? sessionId;
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
yield* discardResponseBody(response);
|
|
52
|
+
return yield* fail(new AcpMcpBridgeError(`T3 Code MCP endpoint responded with HTTP ${response.status}.`));
|
|
53
|
+
}
|
|
54
|
+
const payloads = yield* runCollect(responsePayloads(response, bridgeError));
|
|
55
|
+
for (const payload of payloads) protocolVersion = protocolVersionOf(payload) ?? protocolVersion;
|
|
56
|
+
return payloads;
|
|
57
|
+
});
|
|
58
|
+
const initializeId = "t3-acp-cli-initialize";
|
|
59
|
+
const initializeResponse = (yield* send({
|
|
60
|
+
jsonrpc: "2.0",
|
|
61
|
+
id: initializeId,
|
|
62
|
+
method: "initialize",
|
|
63
|
+
params: {
|
|
64
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
65
|
+
capabilities: {},
|
|
66
|
+
clientInfo: {
|
|
67
|
+
name: "t3-code-acp-cli",
|
|
68
|
+
version: "0.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
})).find((entry) => asEnvelope(entry)?.id === initializeId);
|
|
72
|
+
if (initializeResponse === void 0 || asEnvelope(initializeResponse)?.error !== void 0) return yield* fail(new AcpMcpBridgeError("T3 Code MCP endpoint rejected initialization."));
|
|
73
|
+
yield* send({
|
|
74
|
+
jsonrpc: "2.0",
|
|
75
|
+
method: "notifications/initialized"
|
|
76
|
+
});
|
|
77
|
+
const callId = "t3-acp-cli-tool-call";
|
|
78
|
+
const envelope = asEnvelope((yield* send({
|
|
79
|
+
jsonrpc: "2.0",
|
|
80
|
+
id: callId,
|
|
81
|
+
method: "tools/call",
|
|
82
|
+
params: {
|
|
83
|
+
name: options.tool,
|
|
84
|
+
arguments: options.arguments
|
|
85
|
+
}
|
|
86
|
+
})).find((entry) => asEnvelope(entry)?.id === callId));
|
|
87
|
+
if (envelope === null || envelope.error !== void 0) return yield* fail(new AcpMcpBridgeError(`T3 Code MCP tool call failed${envelope?.error === void 0 ? "." : `: ${JSON.stringify(envelope.error)}`}`));
|
|
88
|
+
return envelope.result;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function runAcpMcpStdioBridge(options) {
|
|
92
|
+
const fetchImplementation = options.fetchImplementation ?? fetch;
|
|
93
|
+
return gen(function* () {
|
|
94
|
+
let sessionId = null;
|
|
95
|
+
let protocolVersion = null;
|
|
96
|
+
const running = /* @__PURE__ */ new Set();
|
|
97
|
+
const writeMessage = (message) => sync(() => {
|
|
98
|
+
options.output.write(`${JSON.stringify(message)}\n`);
|
|
99
|
+
});
|
|
100
|
+
const handleServerPayload = (payload) => gen(function* () {
|
|
101
|
+
for (const entry of Array.isArray(payload) ? payload : [payload]) {
|
|
102
|
+
protocolVersion = protocolVersionOf(entry) ?? protocolVersion;
|
|
103
|
+
yield* writeMessage(entry);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
const respondWithError = (requestId, message, code = -32603) => writeMessage({
|
|
107
|
+
jsonrpc: "2.0",
|
|
108
|
+
id: requestId ?? null,
|
|
109
|
+
error: {
|
|
110
|
+
code,
|
|
111
|
+
message
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
const forward = (line, envelope) => gen(function* () {
|
|
115
|
+
const response = yield* tryPromise({
|
|
116
|
+
try: () => fetchImplementation(options.endpoint, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: {
|
|
119
|
+
"content-type": "application/json",
|
|
120
|
+
accept: "application/json, text/event-stream",
|
|
121
|
+
authorization: options.authorization,
|
|
122
|
+
...sessionId === null ? {} : { "mcp-session-id": sessionId },
|
|
123
|
+
...protocolVersion === null ? {} : { "mcp-protocol-version": protocolVersion }
|
|
124
|
+
},
|
|
125
|
+
body: line
|
|
126
|
+
}),
|
|
127
|
+
catch: bridgeError
|
|
128
|
+
});
|
|
129
|
+
sessionId = response.headers.get("mcp-session-id") ?? sessionId;
|
|
130
|
+
if (!response.ok) {
|
|
131
|
+
if (envelope.id !== void 0) yield* respondWithError(envelope.id, `T3 Code MCP endpoint responded with HTTP ${response.status}.`);
|
|
132
|
+
return yield* discardResponseBody(response);
|
|
133
|
+
}
|
|
134
|
+
yield* runForEach(responsePayloads(response, bridgeError), handleServerPayload);
|
|
135
|
+
}).pipe(catchCause((cause) => {
|
|
136
|
+
if (envelope.id === void 0) return void_;
|
|
137
|
+
const error = squash(cause);
|
|
138
|
+
return respondWithError(envelope.id, `T3 Code MCP bridge request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
}));
|
|
140
|
+
let sessionBarrier = void_;
|
|
141
|
+
let sessionBarrierPending = false;
|
|
142
|
+
const launch = (task) => gen(function* () {
|
|
143
|
+
const fiber = yield* forkChild(task);
|
|
144
|
+
running.add(fiber);
|
|
145
|
+
yield* forkChild(await_(fiber).pipe(andThen(sync(() => {
|
|
146
|
+
running.delete(fiber);
|
|
147
|
+
}))));
|
|
148
|
+
});
|
|
149
|
+
const dispatch = (line) => gen(function* () {
|
|
150
|
+
if (line.trim().length === 0) return;
|
|
151
|
+
let parsed;
|
|
152
|
+
try {
|
|
153
|
+
parsed = JSON.parse(line);
|
|
154
|
+
} catch {
|
|
155
|
+
return yield* respondWithError(null, "Parse error", -32700);
|
|
156
|
+
}
|
|
157
|
+
const envelope = asEnvelope(parsed);
|
|
158
|
+
if (envelope === null) return;
|
|
159
|
+
const isResponse = envelope.id !== void 0 && ("result" in envelope || "error" in envelope);
|
|
160
|
+
const isSessionHandshake = envelope.method === "initialize" || envelope.method === "notifications/initialized";
|
|
161
|
+
if (isResponse) return yield* launch(forward(line, envelope));
|
|
162
|
+
if (isSessionHandshake) {
|
|
163
|
+
const fiber = yield* forkChild(sessionBarrier.pipe(andThen(forward(line, envelope))));
|
|
164
|
+
running.add(fiber);
|
|
165
|
+
const barrier = await_(fiber).pipe(asVoid);
|
|
166
|
+
sessionBarrier = barrier;
|
|
167
|
+
sessionBarrierPending = true;
|
|
168
|
+
yield* forkChild(await_(fiber).pipe(andThen(sync(() => {
|
|
169
|
+
running.delete(fiber);
|
|
170
|
+
if (sessionBarrier === barrier) sessionBarrierPending = false;
|
|
171
|
+
}))));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const task = sessionBarrierPending ? sessionBarrier.pipe(andThen(forward(line, envelope))) : forward(line, envelope);
|
|
175
|
+
return yield* launch(task);
|
|
176
|
+
});
|
|
177
|
+
const reader = NodeReadline.createInterface({ input: options.input });
|
|
178
|
+
yield* runForEach(fromAsyncIterable(reader, bridgeError), dispatch).pipe(catchCause(() => void_));
|
|
179
|
+
yield* awaitAll(running);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Kept free of heavy imports: these commands run on the ACP first-message
|
|
184
|
+
* critical path.
|
|
185
|
+
*/
|
|
186
|
+
async function runAcpMcpCliFastPath(command, args) {
|
|
187
|
+
const endpoint = process.env.T3_ACP_MCP_ENDPOINT;
|
|
188
|
+
const authorization = process.env.T3_ACP_MCP_AUTHORIZATION;
|
|
189
|
+
if (endpoint === void 0 || authorization === void 0) {
|
|
190
|
+
process.stderr.write(`${command} requires T3_ACP_MCP_ENDPOINT and T3_ACP_MCP_AUTHORIZATION.\n`);
|
|
191
|
+
process.exitCode = 2;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (command === "acp-mcp-bridge") {
|
|
195
|
+
await runPromise(runAcpMcpStdioBridge({
|
|
196
|
+
endpoint,
|
|
197
|
+
authorization,
|
|
198
|
+
input: process.stdin,
|
|
199
|
+
output: process.stdout
|
|
200
|
+
}));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const [tool, argumentsJson] = args;
|
|
204
|
+
if (tool === void 0 || argumentsJson === void 0) {
|
|
205
|
+
process.stderr.write("acp-mcp-call requires <tool> and <arguments-json>.\n");
|
|
206
|
+
process.exitCode = 2;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
let parsed;
|
|
210
|
+
try {
|
|
211
|
+
parsed = JSON.parse(argumentsJson);
|
|
212
|
+
} catch {
|
|
213
|
+
process.stderr.write("acp-mcp-call arguments must be valid JSON.\n");
|
|
214
|
+
process.exitCode = 2;
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
218
|
+
process.stderr.write("acp-mcp-call arguments must be a JSON object.\n");
|
|
219
|
+
process.exitCode = 2;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const result = await runPromise(callAcpMcpTool({
|
|
223
|
+
endpoint,
|
|
224
|
+
authorization,
|
|
225
|
+
tool,
|
|
226
|
+
arguments: parsed
|
|
227
|
+
}));
|
|
228
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
229
|
+
}
|
|
230
|
+
//#endregion
|
|
231
|
+
export { runAcpMcpStdioBridge as i, callAcpMcpTool as n, runAcpMcpCliFastPath as r, AcpMcpBridgeError as t };
|
|
232
|
+
|
|
233
|
+
//# sourceMappingURL=AcpMcpStdioBridge-ZWAIz2dT.mjs.map
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Ma as currentTimeNanos$1, Oa as clockWith$1, co as monotonicTimeNanos$1, ja as currentTimeMillis$1, ya as ClockRef } from "./Effect-DXlc4A9S.mjs";
|
|
4
|
+
//#region ../../node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Clock.js
|
|
5
|
+
/**
|
|
6
|
+
* Context reference for the active time service in the environment.
|
|
7
|
+
*
|
|
8
|
+
* **When to use**
|
|
9
|
+
*
|
|
10
|
+
* Use when you need to access or provide the full time service, including sleep
|
|
11
|
+
* operations, rather than a single timestamp accessor.
|
|
12
|
+
*
|
|
13
|
+
* **Example** (Accessing the Clock service)
|
|
14
|
+
*
|
|
15
|
+
* ```ts import.meta.vitest
|
|
16
|
+
* import { Clock, Effect } from "effect"
|
|
17
|
+
*
|
|
18
|
+
* const testClock: Clock.Clock = {
|
|
19
|
+
* currentTimeMillisUnsafe: () => 1_000,
|
|
20
|
+
* currentTimeMillis: Effect.succeed(1_000),
|
|
21
|
+
* monotonicTimeNanosUnsafe: () => 1_000_000_000n,
|
|
22
|
+
* monotonicTimeNanos: Effect.succeed(1_000_000_000n),
|
|
23
|
+
* currentTimeNanosUnsafe: () => 1_000_000_000n,
|
|
24
|
+
* currentTimeNanos: Effect.succeed(1_000_000_000n),
|
|
25
|
+
* sleep: () => Effect.void
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* const program = Effect.gen(function*() {
|
|
29
|
+
* const clock = yield* Clock.Clock
|
|
30
|
+
* return clock.currentTimeMillisUnsafe()
|
|
31
|
+
* })
|
|
32
|
+
*
|
|
33
|
+
* await Effect.runPromise(Effect.provideService(program, Clock.Clock, testClock)) // => 1_000
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @see {@link clockWith} for using the current Clock service inside an effect
|
|
37
|
+
* @see {@link currentTimeMillis} for reading the current time in milliseconds
|
|
38
|
+
* @see {@link currentTimeNanos} for reading the current time in nanoseconds
|
|
39
|
+
*
|
|
40
|
+
* @stability stable
|
|
41
|
+
* @category services
|
|
42
|
+
* @since 2.0.0
|
|
43
|
+
*/
|
|
44
|
+
const Clock = ClockRef;
|
|
45
|
+
/**
|
|
46
|
+
* Accesses the current Clock service and uses it to run the provided function.
|
|
47
|
+
*
|
|
48
|
+
* **When to use**
|
|
49
|
+
*
|
|
50
|
+
* Use when you need the full Clock service interface to perform multiple time
|
|
51
|
+
* operations or call unsafe variants within a single effect.
|
|
52
|
+
*
|
|
53
|
+
* **Example** (Accessing the current Clock service)
|
|
54
|
+
*
|
|
55
|
+
* ```ts import.meta.vitest
|
|
56
|
+
* import { Clock, Effect } from "effect"
|
|
57
|
+
*
|
|
58
|
+
* const testClock: Clock.Clock = {
|
|
59
|
+
* currentTimeMillisUnsafe: () => 1_000,
|
|
60
|
+
* currentTimeMillis: Effect.succeed(1_000),
|
|
61
|
+
* monotonicTimeNanosUnsafe: () => 1_000_000_000n,
|
|
62
|
+
* monotonicTimeNanos: Effect.succeed(1_000_000_000n),
|
|
63
|
+
* currentTimeNanosUnsafe: () => 1_000_000_000n,
|
|
64
|
+
* currentTimeNanos: Effect.succeed(1_000_000_000n),
|
|
65
|
+
* sleep: () => Effect.void
|
|
66
|
+
* }
|
|
67
|
+
*
|
|
68
|
+
* const program = Clock.clockWith((clock) => Effect.sync(() => clock.currentTimeMillisUnsafe()))
|
|
69
|
+
*
|
|
70
|
+
* await Effect.runPromise(Effect.provideService(program, Clock.Clock, testClock)) // => 1_000
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @see {@link Clock} for the service reference
|
|
74
|
+
* @see {@link currentTimeMillis} for convenience accessor that returns milliseconds
|
|
75
|
+
* @see {@link currentTimeNanos} for convenience accessor that returns nanoseconds
|
|
76
|
+
* @stability stable
|
|
77
|
+
* @category accessors
|
|
78
|
+
* @since 2.0.0
|
|
79
|
+
*/
|
|
80
|
+
const clockWith = clockWith$1;
|
|
81
|
+
/**
|
|
82
|
+
* Returns an Effect that succeeds with the current Unix time in milliseconds.
|
|
83
|
+
*
|
|
84
|
+
* **When to use**
|
|
85
|
+
*
|
|
86
|
+
* Use to create wall-clock timestamps from the active `Clock` service with
|
|
87
|
+
* millisecond precision.
|
|
88
|
+
*
|
|
89
|
+
* **Gotchas**
|
|
90
|
+
*
|
|
91
|
+
* The value can move backward or forward when the system wall clock is
|
|
92
|
+
* corrected, so it is not suitable for measuring elapsed time.
|
|
93
|
+
*
|
|
94
|
+
* **Example** (Reading milliseconds)
|
|
95
|
+
*
|
|
96
|
+
* ```ts import.meta.vitest
|
|
97
|
+
* import { Clock, Effect } from "effect"
|
|
98
|
+
*
|
|
99
|
+
* const testClock: Clock.Clock = {
|
|
100
|
+
* currentTimeMillisUnsafe: () => 1_000,
|
|
101
|
+
* currentTimeMillis: Effect.succeed(1_000),
|
|
102
|
+
* monotonicTimeNanosUnsafe: () => 1_000_000_000n,
|
|
103
|
+
* monotonicTimeNanos: Effect.succeed(1_000_000_000n),
|
|
104
|
+
* currentTimeNanosUnsafe: () => 1_000_000_000n,
|
|
105
|
+
* currentTimeNanos: Effect.succeed(1_000_000_000n),
|
|
106
|
+
* sleep: () => Effect.void
|
|
107
|
+
* }
|
|
108
|
+
*
|
|
109
|
+
* await Effect.runPromise(Effect.provideService(Clock.currentTimeMillis, Clock.Clock, testClock)) // => 1_000
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @see {@link currentTimeNanos} for nanosecond precision
|
|
113
|
+
* @see {@link monotonicTimeNanos} for measuring elapsed time
|
|
114
|
+
* @see {@link clockWith} for accessing the full Clock service
|
|
115
|
+
*
|
|
116
|
+
* @stability stable
|
|
117
|
+
* @category accessors
|
|
118
|
+
* @since 2.0.0
|
|
119
|
+
*/
|
|
120
|
+
const currentTimeMillis = currentTimeMillis$1;
|
|
121
|
+
/**
|
|
122
|
+
* Returns an Effect that succeeds with the current Unix time in nanoseconds.
|
|
123
|
+
*
|
|
124
|
+
* **When to use**
|
|
125
|
+
*
|
|
126
|
+
* Use to create wall-clock timestamps from the active `Clock` service with
|
|
127
|
+
* nanosecond precision.
|
|
128
|
+
*
|
|
129
|
+
* **Gotchas**
|
|
130
|
+
*
|
|
131
|
+
* The value can move backward or forward when the system wall clock is
|
|
132
|
+
* corrected, so it is not suitable for measuring elapsed time.
|
|
133
|
+
* The live clock allows up to one second of drift from `Date.now()` before
|
|
134
|
+
* re-anchoring.
|
|
135
|
+
*
|
|
136
|
+
* **Example** (Reading nanoseconds)
|
|
137
|
+
*
|
|
138
|
+
* ```ts import.meta.vitest
|
|
139
|
+
* import { Clock, Effect } from "effect"
|
|
140
|
+
*
|
|
141
|
+
* const testClock: Clock.Clock = {
|
|
142
|
+
* currentTimeMillisUnsafe: () => 1_000,
|
|
143
|
+
* currentTimeMillis: Effect.succeed(1_000),
|
|
144
|
+
* monotonicTimeNanosUnsafe: () => 1_000_000_000n,
|
|
145
|
+
* monotonicTimeNanos: Effect.succeed(1_000_000_000n),
|
|
146
|
+
* currentTimeNanosUnsafe: () => 1_000_000_000n,
|
|
147
|
+
* currentTimeNanos: Effect.succeed(1_000_000_000n),
|
|
148
|
+
* sleep: () => Effect.void
|
|
149
|
+
* }
|
|
150
|
+
*
|
|
151
|
+
* await Effect.runPromise(Effect.provideService(Clock.currentTimeNanos, Clock.Clock, testClock)) // => 1_000_000_000n
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @see {@link monotonicTimeNanos} for measuring elapsed time
|
|
155
|
+
*
|
|
156
|
+
* @stability stable
|
|
157
|
+
* @category accessors
|
|
158
|
+
* @since 2.0.0
|
|
159
|
+
*/
|
|
160
|
+
const currentTimeNanos = currentTimeNanos$1;
|
|
161
|
+
/**
|
|
162
|
+
* Returns an Effect that succeeds with the current monotonic time in
|
|
163
|
+
* nanoseconds.
|
|
164
|
+
*
|
|
165
|
+
* **When to use**
|
|
166
|
+
*
|
|
167
|
+
* Use to measure elapsed time by subtracting two readings.
|
|
168
|
+
*
|
|
169
|
+
* **Gotchas**
|
|
170
|
+
*
|
|
171
|
+
* The value has an arbitrary origin and is unsuitable for serialization. Use
|
|
172
|
+
* it only to subtract readings produced by the same clock. Whether it advances
|
|
173
|
+
* while the host is suspended depends on the runtime.
|
|
174
|
+
*
|
|
175
|
+
* @see {@link currentTimeNanos} for Unix wall-clock timestamps
|
|
176
|
+
*
|
|
177
|
+
* @stability stable
|
|
178
|
+
* @category accessors
|
|
179
|
+
* @since 4.0.0
|
|
180
|
+
*/
|
|
181
|
+
const monotonicTimeNanos = monotonicTimeNanos$1;
|
|
182
|
+
//#endregion
|
|
183
|
+
export { monotonicTimeNanos as a, currentTimeNanos as i, clockWith as n, currentTimeMillis as r, Clock as t };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=Clock-B88OfuDl.mjs.map
|