effect-inspect 0.1.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.
- package/README.md +122 -0
- package/app/dist/client/assets/index-smV05cfr.js +25 -0
- package/app/dist/client/assets/rolldown-runtime-CbXtAM7H.js +1 -0
- package/app/dist/client/assets/routes-TKgeFdSW.js +5 -0
- package/app/dist/client/assets/styles-B3rAZGvS.css +2 -0
- package/app/dist/server/assets/_tanstack-start-manifest_v-Co953HeC.js +20 -0
- package/app/dist/server/assets/empty-plugin-adapters-D9UWiqvJ.js +5 -0
- package/app/dist/server/assets/router-CN98Ramo.js +491 -0
- package/app/dist/server/assets/routes-eZ4XqxE9.js +3999 -0
- package/app/dist/server/assets/start-5Z2QO8AU.js +4 -0
- package/app/dist/server/server.js +1812 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +29 -0
- package/dist/client/Client.d.ts +52 -0
- package/dist/client/Client.js +224 -0
- package/dist/client/Edge.d.ts +31 -0
- package/dist/client/Edge.js +108 -0
- package/dist/client/Inspect.d.ts +49 -0
- package/dist/client/Inspect.js +55 -0
- package/dist/client/Tracer.d.ts +31 -0
- package/dist/client/Tracer.js +119 -0
- package/dist/collector/Config.d.ts +8 -0
- package/dist/collector/Config.js +9 -0
- package/dist/collector/Server.d.ts +24 -0
- package/dist/collector/Server.js +172 -0
- package/dist/collector/Store.d.ts +86 -0
- package/dist/collector/Store.js +119 -0
- package/dist/collector/WebApp.d.ts +3 -0
- package/dist/collector/WebApp.js +36 -0
- package/dist/collector/main.d.ts +1 -0
- package/dist/collector/main.js +22 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/protocol/Codec.d.ts +575 -0
- package/dist/protocol/Codec.js +50 -0
- package/dist/protocol/Schema.d.ts +1237 -0
- package/dist/protocol/Schema.js +327 -0
- package/package.json +85 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The effect-inspect wire protocol.
|
|
3
|
+
*
|
|
4
|
+
* Three unions: {@link ClientMessage} (instrumented program → collector),
|
|
5
|
+
* {@link CollectorMessage} (collector → instrumented program) and
|
|
6
|
+
* {@link WebappMessage} (collector → webapp).
|
|
7
|
+
*
|
|
8
|
+
* Informed by `effect/devtools/DevToolsSchema` but deliberately different:
|
|
9
|
+
* spans are delta-encoded as `SpanStart` / `SpanEnd` rather than a full span
|
|
10
|
+
* snapshot re-sent on end, every message carries a `sessionId`, and attribute
|
|
11
|
+
* values are a bounded {@link Json} union instead of `Schema.Any`.
|
|
12
|
+
*/
|
|
13
|
+
import { Schema } from 'effect';
|
|
14
|
+
/**
|
|
15
|
+
* Monotonic nanosecond timestamp, matching `Tracer.Span#startTime`.
|
|
16
|
+
*
|
|
17
|
+
* Carried as a decimal string on the wire because JSON numbers cannot hold
|
|
18
|
+
* nanos without precision loss.
|
|
19
|
+
*/
|
|
20
|
+
export const Timestamp = Schema.BigIntFromString;
|
|
21
|
+
export const Json = Schema.Union([
|
|
22
|
+
Schema.String,
|
|
23
|
+
Schema.Finite,
|
|
24
|
+
Schema.Boolean,
|
|
25
|
+
Schema.Null,
|
|
26
|
+
Schema.Array(Schema.suspend(() => Json)),
|
|
27
|
+
Schema.Record(Schema.String, Schema.suspend(() => Json)),
|
|
28
|
+
]);
|
|
29
|
+
/** Span attributes, log annotations, and metric/event attributes. */
|
|
30
|
+
export const Attributes = Schema.Record(Schema.String, Json);
|
|
31
|
+
/** Identifies one run of an instrumented program. */
|
|
32
|
+
export const SessionId = Schema.String;
|
|
33
|
+
const sessionId = { sessionId: SessionId };
|
|
34
|
+
/** Mirrors `Tracer.SpanKind`. */
|
|
35
|
+
export const SpanKind = Schema.Literals(['internal', 'server', 'client', 'producer', 'consumer']);
|
|
36
|
+
/** Mirrors `LogLevel.LogLevel`. */
|
|
37
|
+
export const LogLevel = Schema.Literals([
|
|
38
|
+
'All',
|
|
39
|
+
'Fatal',
|
|
40
|
+
'Error',
|
|
41
|
+
'Warn',
|
|
42
|
+
'Info',
|
|
43
|
+
'Debug',
|
|
44
|
+
'Trace',
|
|
45
|
+
'None',
|
|
46
|
+
]);
|
|
47
|
+
/**
|
|
48
|
+
* Wall-clock anchor for a session's monotonic clock.
|
|
49
|
+
*
|
|
50
|
+
* `startTime` is nanos from the same monotonic source as span times;
|
|
51
|
+
* `wallClockEpochMillis` is `Date.now()` sampled at the same instant. Together
|
|
52
|
+
* they let the webapp render absolute times and align sessions with each other.
|
|
53
|
+
*/
|
|
54
|
+
export const Clock = Schema.Struct({
|
|
55
|
+
startTime: Timestamp,
|
|
56
|
+
wallClockEpochMillis: Schema.Natural,
|
|
57
|
+
});
|
|
58
|
+
/** First message on a client connection; opens the session. */
|
|
59
|
+
export const Hello = Schema.Struct({
|
|
60
|
+
_tag: Schema.tag('Hello'),
|
|
61
|
+
...sessionId,
|
|
62
|
+
program: Schema.String,
|
|
63
|
+
pid: Schema.Natural,
|
|
64
|
+
runtime: Schema.String,
|
|
65
|
+
protocolVersion: Schema.Natural,
|
|
66
|
+
clock: Clock,
|
|
67
|
+
});
|
|
68
|
+
/** The protocol version a `Hello` must carry. Bump on any breaking change. */
|
|
69
|
+
export const protocolVersion = 1;
|
|
70
|
+
/**
|
|
71
|
+
* A span parent that lives outside this session's span tree — propagated from
|
|
72
|
+
* another tracing system, so the collector has ids but no span body.
|
|
73
|
+
*/
|
|
74
|
+
export const ExternalParent = Schema.Struct({
|
|
75
|
+
_tag: Schema.tag('ExternalParent'),
|
|
76
|
+
spanId: Schema.String,
|
|
77
|
+
traceId: Schema.String,
|
|
78
|
+
sampled: Schema.Boolean,
|
|
79
|
+
});
|
|
80
|
+
/** A span parent within this session, referenced by id only. */
|
|
81
|
+
export const LocalParent = Schema.Struct({
|
|
82
|
+
_tag: Schema.tag('LocalParent'),
|
|
83
|
+
spanId: Schema.String,
|
|
84
|
+
});
|
|
85
|
+
export const SpanParent = Schema.Union([LocalParent, ExternalParent]);
|
|
86
|
+
/**
|
|
87
|
+
* A span opened. Sent once, when the span starts — never re-sent.
|
|
88
|
+
*
|
|
89
|
+
* `parent` is absent for a root span.
|
|
90
|
+
*/
|
|
91
|
+
export const SpanStart = Schema.Struct({
|
|
92
|
+
_tag: Schema.tag('SpanStart'),
|
|
93
|
+
...sessionId,
|
|
94
|
+
spanId: Schema.String,
|
|
95
|
+
traceId: Schema.String,
|
|
96
|
+
parent: Schema.optional(SpanParent),
|
|
97
|
+
name: Schema.String,
|
|
98
|
+
kind: SpanKind,
|
|
99
|
+
startTime: Timestamp,
|
|
100
|
+
attributes: Attributes,
|
|
101
|
+
sampled: Schema.Boolean,
|
|
102
|
+
fiberId: Schema.optional(Schema.Natural),
|
|
103
|
+
});
|
|
104
|
+
/**
|
|
105
|
+
* How a span finished.
|
|
106
|
+
*
|
|
107
|
+
* The full `Cause` is not carried: the webapp only needs to colour the span and
|
|
108
|
+
* show a message, so the producer flattens failures to `error` (rendered
|
|
109
|
+
* message) plus optional `stack`. `_tag: "Failure"` covers expected errors,
|
|
110
|
+
* defects and interrupts alike, distinguished by `kind`.
|
|
111
|
+
*/
|
|
112
|
+
export const SpanOutcomeSuccess = Schema.Struct({
|
|
113
|
+
_tag: Schema.tag('Success'),
|
|
114
|
+
});
|
|
115
|
+
export const SpanOutcomeFailure = Schema.Struct({
|
|
116
|
+
_tag: Schema.tag('Failure'),
|
|
117
|
+
kind: Schema.Literals(['Fail', 'Die', 'Interrupt']),
|
|
118
|
+
error: Schema.String,
|
|
119
|
+
stack: Schema.optional(Schema.String),
|
|
120
|
+
});
|
|
121
|
+
export const SpanOutcome = Schema.Union([SpanOutcomeSuccess, SpanOutcomeFailure]);
|
|
122
|
+
/**
|
|
123
|
+
* A span closed.
|
|
124
|
+
*
|
|
125
|
+
* `attributes` carries only attributes added after `SpanStart` was sent; the
|
|
126
|
+
* collector merges them over the ones it already has.
|
|
127
|
+
*/
|
|
128
|
+
export const SpanEnd = Schema.Struct({
|
|
129
|
+
_tag: Schema.tag('SpanEnd'),
|
|
130
|
+
...sessionId,
|
|
131
|
+
spanId: Schema.String,
|
|
132
|
+
endTime: Timestamp,
|
|
133
|
+
outcome: SpanOutcome,
|
|
134
|
+
attributes: Attributes,
|
|
135
|
+
});
|
|
136
|
+
/** A point-in-time event recorded against a span. */
|
|
137
|
+
export const SpanEvent = Schema.Struct({
|
|
138
|
+
_tag: Schema.tag('SpanEvent'),
|
|
139
|
+
...sessionId,
|
|
140
|
+
spanId: Schema.String,
|
|
141
|
+
name: Schema.String,
|
|
142
|
+
time: Timestamp,
|
|
143
|
+
attributes: Attributes,
|
|
144
|
+
});
|
|
145
|
+
/** A log record, in the same ordered stream as spans. */
|
|
146
|
+
export const Log = Schema.Struct({
|
|
147
|
+
_tag: Schema.tag('Log'),
|
|
148
|
+
...sessionId,
|
|
149
|
+
time: Timestamp,
|
|
150
|
+
level: LogLevel,
|
|
151
|
+
message: Json,
|
|
152
|
+
spanId: Schema.optional(Schema.String),
|
|
153
|
+
fiberId: Schema.optional(Schema.Natural),
|
|
154
|
+
annotations: Attributes,
|
|
155
|
+
});
|
|
156
|
+
const metric = (type, state) => Schema.Struct({
|
|
157
|
+
type: Schema.tag(type),
|
|
158
|
+
name: Schema.String,
|
|
159
|
+
description: Schema.optional(Schema.String),
|
|
160
|
+
attributes: Schema.Record(Schema.String, Schema.String),
|
|
161
|
+
state,
|
|
162
|
+
});
|
|
163
|
+
export const Counter = metric('Counter', Schema.Struct({ count: Schema.Natural, incremental: Schema.Boolean }));
|
|
164
|
+
export const Gauge = metric('Gauge', Schema.Struct({ value: Schema.Finite }));
|
|
165
|
+
export const Histogram = metric('Histogram', Schema.Struct({
|
|
166
|
+
buckets: Schema.Array(Schema.Tuple([Schema.Finite, Schema.Natural])),
|
|
167
|
+
count: Schema.Natural,
|
|
168
|
+
min: Schema.Finite,
|
|
169
|
+
max: Schema.Finite,
|
|
170
|
+
sum: Schema.Finite,
|
|
171
|
+
}));
|
|
172
|
+
export const Frequency = metric('Frequency', Schema.Struct({ occurrences: Schema.Record(Schema.String, Schema.Natural) }));
|
|
173
|
+
export const Summary = metric('Summary', Schema.Struct({
|
|
174
|
+
quantiles: Schema.Array(Schema.Tuple([
|
|
175
|
+
Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 1 })),
|
|
176
|
+
Schema.NullOr(Schema.Finite),
|
|
177
|
+
])),
|
|
178
|
+
count: Schema.Natural,
|
|
179
|
+
min: Schema.Finite,
|
|
180
|
+
max: Schema.Finite,
|
|
181
|
+
sum: Schema.Finite,
|
|
182
|
+
}));
|
|
183
|
+
export const Metric = Schema.Union([Counter, Gauge, Histogram, Frequency, Summary]);
|
|
184
|
+
/** A snapshot of every metric, taken at `time`. */
|
|
185
|
+
export const Metrics = Schema.Struct({
|
|
186
|
+
_tag: Schema.tag('Metrics'),
|
|
187
|
+
...sessionId,
|
|
188
|
+
time: Timestamp,
|
|
189
|
+
metrics: Schema.Array(Metric),
|
|
190
|
+
});
|
|
191
|
+
/** A fiber lifecycle transition. */
|
|
192
|
+
export const FiberEvent = Schema.Struct({
|
|
193
|
+
_tag: Schema.tag('FiberEvent'),
|
|
194
|
+
...sessionId,
|
|
195
|
+
fiberId: Schema.Natural,
|
|
196
|
+
event: Schema.Literals(['Start', 'End', 'Suspend', 'Resume']),
|
|
197
|
+
parentFiberId: Schema.optional(Schema.Natural),
|
|
198
|
+
time: Timestamp,
|
|
199
|
+
});
|
|
200
|
+
/**
|
|
201
|
+
* A `process.memoryUsage()` reading, sampled on an interval by the client.
|
|
202
|
+
*
|
|
203
|
+
* Node and Bun only: a runtime without `process.memoryUsage` emits none of
|
|
204
|
+
* these and a session simply has no memory track. Figures are bytes, as the
|
|
205
|
+
* runtime reports them; `time` shares the monotonic base of span times, so the
|
|
206
|
+
* webapp can draw the curve against the same x-axis as the flame chart.
|
|
207
|
+
*/
|
|
208
|
+
export const MemorySample = Schema.Struct({
|
|
209
|
+
_tag: Schema.tag('MemorySample'),
|
|
210
|
+
...sessionId,
|
|
211
|
+
time: Timestamp,
|
|
212
|
+
heapUsed: Schema.Natural,
|
|
213
|
+
heapTotal: Schema.Natural,
|
|
214
|
+
rss: Schema.Natural,
|
|
215
|
+
external: Schema.Natural,
|
|
216
|
+
});
|
|
217
|
+
export const Ping = Schema.Struct({
|
|
218
|
+
_tag: Schema.tag('Ping'),
|
|
219
|
+
...sessionId,
|
|
220
|
+
});
|
|
221
|
+
export const Pong = Schema.Struct({
|
|
222
|
+
_tag: Schema.tag('Pong'),
|
|
223
|
+
...sessionId,
|
|
224
|
+
});
|
|
225
|
+
/** Asks the client for a {@link Metrics} snapshot. */
|
|
226
|
+
export const MetricsRequest = Schema.Struct({
|
|
227
|
+
_tag: Schema.tag('MetricsRequest'),
|
|
228
|
+
});
|
|
229
|
+
/** Telemetry the instrumented program sends to the collector. */
|
|
230
|
+
export const ClientMessage = Schema.Union([
|
|
231
|
+
Hello,
|
|
232
|
+
SpanStart,
|
|
233
|
+
SpanEnd,
|
|
234
|
+
SpanEvent,
|
|
235
|
+
Log,
|
|
236
|
+
Metrics,
|
|
237
|
+
FiberEvent,
|
|
238
|
+
MemorySample,
|
|
239
|
+
Ping,
|
|
240
|
+
]);
|
|
241
|
+
/** What the collector sends back to the instrumented program. */
|
|
242
|
+
export const CollectorMessage = Schema.Union([Pong, MetricsRequest]);
|
|
243
|
+
/** A session the collector knows about, as listed to the webapp. */
|
|
244
|
+
export const Session = Schema.Struct({
|
|
245
|
+
sessionId: SessionId,
|
|
246
|
+
program: Schema.String,
|
|
247
|
+
pid: Schema.Natural,
|
|
248
|
+
runtime: Schema.String,
|
|
249
|
+
clock: Clock,
|
|
250
|
+
active: Schema.Boolean,
|
|
251
|
+
endedAtEpochMillis: Schema.optional(Schema.Natural),
|
|
252
|
+
});
|
|
253
|
+
/** Every session the collector holds. Sent on connect and on change. */
|
|
254
|
+
export const SessionList = Schema.Struct({
|
|
255
|
+
_tag: Schema.tag('SessionList'),
|
|
256
|
+
sessions: Schema.Array(Session),
|
|
257
|
+
});
|
|
258
|
+
/**
|
|
259
|
+
* Everything already recorded for a session, replayed in arrival order.
|
|
260
|
+
*
|
|
261
|
+
* Sent once when the webapp subscribes, before any live telemetry for that
|
|
262
|
+
* session. `complete` is false when the backlog is split across several
|
|
263
|
+
* messages, so the webapp knows more is coming.
|
|
264
|
+
*/
|
|
265
|
+
export const Backlog = Schema.Struct({
|
|
266
|
+
_tag: Schema.tag('Backlog'),
|
|
267
|
+
...sessionId,
|
|
268
|
+
messages: Schema.Array(ClientMessage),
|
|
269
|
+
complete: Schema.Boolean,
|
|
270
|
+
});
|
|
271
|
+
/** A live client message forwarded to the webapp as it arrives. */
|
|
272
|
+
export const Live = Schema.Struct({
|
|
273
|
+
_tag: Schema.tag('Live'),
|
|
274
|
+
message: ClientMessage,
|
|
275
|
+
});
|
|
276
|
+
/**
|
|
277
|
+
* A session ended — its program exited or its connection dropped.
|
|
278
|
+
*
|
|
279
|
+
* **Nothing emits this.** The collector marks the session `active: false` and
|
|
280
|
+
* re-sends the whole {@link SessionList} on every change, which already tells
|
|
281
|
+
* the webapp everything this message would. The variant is kept because the
|
|
282
|
+
* protocol is extended additively and removing it would break the union for
|
|
283
|
+
* anyone decoding an older stream; the webapp handler for it was deleted
|
|
284
|
+
* rather than left looking implemented.
|
|
285
|
+
*/
|
|
286
|
+
export const SessionEnded = Schema.Struct({
|
|
287
|
+
_tag: Schema.tag('SessionEnded'),
|
|
288
|
+
...sessionId,
|
|
289
|
+
endedAtEpochMillis: Schema.Natural,
|
|
290
|
+
});
|
|
291
|
+
/** What the collector sends to the webapp. */
|
|
292
|
+
export const WebappMessage = Schema.Union([SessionList, Backlog, Live, SessionEnded]);
|
|
293
|
+
/** Asks the collector to stream one session: its backlog, then live messages. */
|
|
294
|
+
export const Subscribe = Schema.Struct({
|
|
295
|
+
_tag: Schema.tag('Subscribe'),
|
|
296
|
+
...sessionId,
|
|
297
|
+
});
|
|
298
|
+
/** Stops the stream started by {@link Subscribe}. */
|
|
299
|
+
export const Unsubscribe = Schema.Struct({
|
|
300
|
+
_tag: Schema.tag('Unsubscribe'),
|
|
301
|
+
...sessionId,
|
|
302
|
+
});
|
|
303
|
+
/** What the webapp sends to the collector. */
|
|
304
|
+
export const WebappRequest = Schema.Union([Subscribe, Unsubscribe]);
|
|
305
|
+
/**
|
|
306
|
+
* Line 1 of a saved trace file.
|
|
307
|
+
*
|
|
308
|
+
* The rest of the file is {@link ClientMessage} NDJSON, byte-identical to what
|
|
309
|
+
* the wire carries — a trace file is the protocol message stream with a header
|
|
310
|
+
* on top, not a second representation of a trace. So any new `ClientMessage`
|
|
311
|
+
* variant is carried by a saved trace for free, and {@link traceFileFormatVersion}
|
|
312
|
+
* only moves if *this* struct or the line layout changes.
|
|
313
|
+
*
|
|
314
|
+
* The full {@link Session} is embedded because a loaded trace has no
|
|
315
|
+
* `SessionList` to get its `clock` from, and without the clock the webapp
|
|
316
|
+
* cannot show absolute times.
|
|
317
|
+
*/
|
|
318
|
+
export const TraceFileHeader = Schema.Struct({
|
|
319
|
+
_tag: Schema.tag('TraceFileHeader'),
|
|
320
|
+
formatVersion: Schema.Natural,
|
|
321
|
+
/** {@link protocolVersion} at save time. Recorded for diagnosis, not enforced. */
|
|
322
|
+
protocolVersion: Schema.Natural,
|
|
323
|
+
session: Session,
|
|
324
|
+
savedAtEpochMillis: Schema.Natural,
|
|
325
|
+
});
|
|
326
|
+
/** The trace file layout version. Bump only on a change to the header or the line layout. */
|
|
327
|
+
export const traceFileFormatVersion = 1;
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "effect-inspect",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "A live inspector for Effect programs",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/julia-script/effect-inspect.git"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"effect-inspect": "dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"app/dist"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"lint": "oxlint --disable-nested-config .",
|
|
31
|
+
"collector": "bun run src/collector/main.ts",
|
|
32
|
+
"format": "oxfmt --write .",
|
|
33
|
+
"check": "oxfmt --check . && oxlint --disable-nested-config . && bun run typecheck",
|
|
34
|
+
"test": "bun test src app",
|
|
35
|
+
"check:write": "oxfmt --write . && oxlint --disable-nested-config --fix .",
|
|
36
|
+
"prepare": "effect-tsgo patch --oxlint",
|
|
37
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && bun run build:app",
|
|
38
|
+
"dev": "tsc --watch --preserveWatchOutput",
|
|
39
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p app/tsconfig.json && tsc --noEmit -p examples/tsconfig.json",
|
|
40
|
+
"dev:app": "vite dev --config app/vite.config.ts",
|
|
41
|
+
"build:app": "vite build --config app/vite.config.ts",
|
|
42
|
+
"stub:collector": "bun run app/stub-collector.ts",
|
|
43
|
+
"example:webapp": "bun run examples/webapp.ts",
|
|
44
|
+
"example:concurrent": "bun run examples/concurrent.ts",
|
|
45
|
+
"example:deep": "bun run examples/deep.ts",
|
|
46
|
+
"example:failing": "bun run examples/failing.ts",
|
|
47
|
+
"example:slow": "bun run examples/slow.ts",
|
|
48
|
+
"example:firehose": "bun run examples/firehose.ts"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@effect/atom-react": "4.0.0-rc.117",
|
|
52
|
+
"@effect/platform-node": "4.0.0-rc.117",
|
|
53
|
+
"@tanstack/react-router": "^1.170.39",
|
|
54
|
+
"@tanstack/react-start": "^1.168.58",
|
|
55
|
+
"class-variance-authority": "^0.7.1",
|
|
56
|
+
"clsx": "^2.1.1",
|
|
57
|
+
"effect": "4.0.0-rc.117",
|
|
58
|
+
"lucide-react": "^1.48.0",
|
|
59
|
+
"react": "^19.3.0",
|
|
60
|
+
"react-dom": "^19.3.0",
|
|
61
|
+
"scheduler": "0.27.0",
|
|
62
|
+
"shadow-plugin": "^2.1.1",
|
|
63
|
+
"tailwind-merge": "^3.7.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@changesets/cli": "^2.29.8",
|
|
67
|
+
"@effect/platform-bun": "4.0.0-rc.117",
|
|
68
|
+
"@effect/tsgo": "0.45.0",
|
|
69
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
70
|
+
"@types/bun": "1.4.2",
|
|
71
|
+
"@types/react": "^19.3.0",
|
|
72
|
+
"@types/react-dom": "^19.3.0",
|
|
73
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
74
|
+
"oxfmt": "0.70.0",
|
|
75
|
+
"oxlint": "1.82.0",
|
|
76
|
+
"oxlint-tsgolint": "7.0.2001",
|
|
77
|
+
"playwright-core": "^1.63.0",
|
|
78
|
+
"tailwindcss": "^4.3.3",
|
|
79
|
+
"typescript": "7.0.2",
|
|
80
|
+
"vite": "^8.3.0"
|
|
81
|
+
},
|
|
82
|
+
"engines": {
|
|
83
|
+
"node": ">=22"
|
|
84
|
+
}
|
|
85
|
+
}
|