svoose 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 +321 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/machine/index.d.ts +18 -0
- package/dist/machine/index.d.ts.map +1 -0
- package/dist/machine/index.js +2 -0
- package/dist/machine/index.js.map +7 -0
- package/dist/machine/machine.svelte.d.ts +26 -0
- package/dist/machine/machine.svelte.d.ts.map +1 -0
- package/dist/machine/machine.svelte.js +2 -0
- package/dist/machine/machine.svelte.js.map +7 -0
- package/dist/machine/types.d.ts +71 -0
- package/dist/machine/types.d.ts.map +1 -0
- package/dist/machine/types.js +1 -0
- package/dist/machine/types.js.map +7 -0
- package/dist/observe/errors.d.ts +23 -0
- package/dist/observe/errors.d.ts.map +1 -0
- package/dist/observe/errors.js +2 -0
- package/dist/observe/errors.js.map +7 -0
- package/dist/observe/index.d.ts +10 -0
- package/dist/observe/index.d.ts.map +1 -0
- package/dist/observe/index.js +2 -0
- package/dist/observe/index.js.map +7 -0
- package/dist/observe/observe.svelte.d.ts +37 -0
- package/dist/observe/observe.svelte.d.ts.map +1 -0
- package/dist/observe/observe.svelte.js +2 -0
- package/dist/observe/observe.svelte.js.map +7 -0
- package/dist/observe/vitals.d.ts +45 -0
- package/dist/observe/vitals.d.ts.map +1 -0
- package/dist/observe/vitals.js +2 -0
- package/dist/observe/vitals.js.map +7 -0
- package/dist/transport/fetch.d.ts +19 -0
- package/dist/transport/fetch.d.ts.map +1 -0
- package/dist/transport/fetch.js +2 -0
- package/dist/transport/fetch.js.map +7 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +2 -0
- package/dist/transport/index.js.map +7 -0
- package/dist/transport/transport.d.ts +12 -0
- package/dist/transport/transport.d.ts.map +1 -0
- package/dist/transport/transport.js +1 -0
- package/dist/transport/transport.js.map +7 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +7 -0
- package/dist/upgrade/after.d.ts +28 -0
- package/dist/upgrade/after.d.ts.map +1 -0
- package/dist/upgrade/history.d.ts +36 -0
- package/dist/upgrade/history.d.ts.map +1 -0
- package/dist/upgrade/index.d.ts +25 -0
- package/dist/upgrade/index.d.ts.map +1 -0
- package/dist/upgrade/invoke.d.ts +39 -0
- package/dist/upgrade/invoke.d.ts.map +1 -0
- package/dist/upgrade/parallel.d.ts +36 -0
- package/dist/upgrade/parallel.d.ts.map +1 -0
- package/dist/upgrade/spawn.d.ts +35 -0
- package/dist/upgrade/spawn.d.ts.map +1 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# svoose
|
|
2
|
+
|
|
3
|
+
> Svelte + Goose = **svoose** — the goose that sees everything
|
|
4
|
+
|
|
5
|
+
Lightweight observability + state machines for Svelte 5. Zero dependencies. Tree-shakeable. **< 3KB gzipped**.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Web Vitals** — CLS, LCP, FID, INP, FCP, TTFB (no external deps)
|
|
10
|
+
- **Error Tracking** — global errors + unhandled rejections
|
|
11
|
+
- **State Machines** — minimal FSM with TypeScript inference
|
|
12
|
+
- **Svelte 5** — works with runes ($state)
|
|
13
|
+
- **Tree-shakeable** — pay only for what you use
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install svoose
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { observe, createMachine } from 'svoose';
|
|
25
|
+
|
|
26
|
+
// Start collecting metrics
|
|
27
|
+
observe({ endpoint: '/api/metrics' });
|
|
28
|
+
|
|
29
|
+
// Create a state machine
|
|
30
|
+
const auth = createMachine({
|
|
31
|
+
id: 'auth',
|
|
32
|
+
initial: 'idle',
|
|
33
|
+
context: { user: null },
|
|
34
|
+
states: {
|
|
35
|
+
idle: { on: { LOGIN: 'loading' } },
|
|
36
|
+
loading: {
|
|
37
|
+
on: {
|
|
38
|
+
SUCCESS: {
|
|
39
|
+
target: 'authenticated',
|
|
40
|
+
action: (ctx, e) => ({ user: e.user }),
|
|
41
|
+
},
|
|
42
|
+
ERROR: 'idle',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
authenticated: { on: { LOGOUT: 'idle' } },
|
|
46
|
+
},
|
|
47
|
+
observe: true, // Track transitions
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Use it
|
|
51
|
+
auth.send('LOGIN');
|
|
52
|
+
auth.state; // 'loading'
|
|
53
|
+
auth.context; // { user: null }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API
|
|
57
|
+
|
|
58
|
+
### `observe(options?)`
|
|
59
|
+
|
|
60
|
+
Start collecting Web Vitals and errors.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const cleanup = observe({
|
|
64
|
+
// Where to send data
|
|
65
|
+
endpoint: '/api/metrics',
|
|
66
|
+
|
|
67
|
+
// Or use custom transport
|
|
68
|
+
transport: myTransport,
|
|
69
|
+
|
|
70
|
+
// What to collect
|
|
71
|
+
vitals: true, // or ['CLS', 'LCP', 'INP']
|
|
72
|
+
errors: true,
|
|
73
|
+
|
|
74
|
+
// Batching
|
|
75
|
+
batchSize: 10,
|
|
76
|
+
flushInterval: 5000,
|
|
77
|
+
|
|
78
|
+
// Sampling
|
|
79
|
+
sampleRate: 0.1, // 10% of users
|
|
80
|
+
|
|
81
|
+
// Debug
|
|
82
|
+
debug: false,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Stop observing
|
|
86
|
+
cleanup();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### `createMachine(config)`
|
|
90
|
+
|
|
91
|
+
Create a state machine.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const machine = createMachine({
|
|
95
|
+
id: 'toggle',
|
|
96
|
+
initial: 'off',
|
|
97
|
+
context: { count: 0 },
|
|
98
|
+
states: {
|
|
99
|
+
off: {
|
|
100
|
+
on: { TOGGLE: 'on' },
|
|
101
|
+
},
|
|
102
|
+
on: {
|
|
103
|
+
entry: (ctx) => ({ count: ctx.count + 1 }),
|
|
104
|
+
on: { TOGGLE: 'off' },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// State & context (reactive in Svelte 5)
|
|
110
|
+
machine.state; // 'off'
|
|
111
|
+
machine.context; // { count: 0 }
|
|
112
|
+
|
|
113
|
+
// Check state
|
|
114
|
+
machine.matches('off'); // true
|
|
115
|
+
machine.matchesAny('on', 'off'); // true
|
|
116
|
+
|
|
117
|
+
// Check if event is valid
|
|
118
|
+
machine.can('TOGGLE'); // true
|
|
119
|
+
|
|
120
|
+
// Send events
|
|
121
|
+
machine.send('TOGGLE');
|
|
122
|
+
machine.send({ type: 'SET', value: 42 });
|
|
123
|
+
|
|
124
|
+
// Cleanup
|
|
125
|
+
machine.destroy();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Guards & Actions
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const counter = createMachine({
|
|
132
|
+
id: 'counter',
|
|
133
|
+
initial: 'active',
|
|
134
|
+
context: { count: 0 },
|
|
135
|
+
states: {
|
|
136
|
+
active: {
|
|
137
|
+
on: {
|
|
138
|
+
INCREMENT: {
|
|
139
|
+
target: 'active',
|
|
140
|
+
guard: (ctx) => ctx.count < 10, // Only if count < 10
|
|
141
|
+
action: (ctx) => ({ count: ctx.count + 1 }),
|
|
142
|
+
},
|
|
143
|
+
DECREMENT: {
|
|
144
|
+
target: 'active',
|
|
145
|
+
guard: (ctx) => ctx.count > 0, // Only if count > 0
|
|
146
|
+
action: (ctx) => ({ count: ctx.count - 1 }),
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Entry & Exit Actions
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const wizard = createMachine({
|
|
158
|
+
id: 'wizard',
|
|
159
|
+
initial: 'step1',
|
|
160
|
+
context: { data: {} },
|
|
161
|
+
states: {
|
|
162
|
+
step1: {
|
|
163
|
+
entry: (ctx) => console.log('Entered step 1'),
|
|
164
|
+
exit: (ctx) => console.log('Leaving step 1'),
|
|
165
|
+
on: { NEXT: 'step2' },
|
|
166
|
+
},
|
|
167
|
+
step2: {
|
|
168
|
+
on: { BACK: 'step1', SUBMIT: 'complete' },
|
|
169
|
+
},
|
|
170
|
+
complete: {
|
|
171
|
+
entry: (ctx) => console.log('Done!'),
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Observability Integration
|
|
178
|
+
|
|
179
|
+
Machines automatically integrate with `observe()`:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Errors include machine context
|
|
183
|
+
observe({ errors: true });
|
|
184
|
+
|
|
185
|
+
const auth = createMachine({
|
|
186
|
+
id: 'auth',
|
|
187
|
+
observe: true, // Track transitions
|
|
188
|
+
// or
|
|
189
|
+
observe: {
|
|
190
|
+
transitions: true,
|
|
191
|
+
context: true, // Include context in events
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// When an error occurs, it includes:
|
|
196
|
+
// { machineId: 'auth', machineState: 'loading', ... }
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Custom Transport
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { observe, createFetchTransport, createConsoleTransport } from 'svoose';
|
|
203
|
+
|
|
204
|
+
// Fetch with custom headers
|
|
205
|
+
const transport = createFetchTransport('/api/metrics', {
|
|
206
|
+
headers: { 'Authorization': 'Bearer xxx' },
|
|
207
|
+
onError: (err) => console.error(err),
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Console (for development)
|
|
211
|
+
observe({ transport: createConsoleTransport({ pretty: true }) });
|
|
212
|
+
|
|
213
|
+
// Custom transport
|
|
214
|
+
const myTransport = {
|
|
215
|
+
async send(events) {
|
|
216
|
+
await myApi.track(events);
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Bundle Size
|
|
222
|
+
|
|
223
|
+
| Import | Size (gzip) |
|
|
224
|
+
|--------|-------------|
|
|
225
|
+
| Full bundle | ~2.9 KB |
|
|
226
|
+
| `observe()` only | ~2.1 KB |
|
|
227
|
+
| `createMachine()` only | ~0.7 KB |
|
|
228
|
+
|
|
229
|
+
## TypeScript
|
|
230
|
+
|
|
231
|
+
Full TypeScript support with inference:
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
type AuthEvent =
|
|
235
|
+
| { type: 'LOGIN'; email: string }
|
|
236
|
+
| { type: 'SUCCESS'; user: User }
|
|
237
|
+
| { type: 'ERROR'; message: string }
|
|
238
|
+
| { type: 'LOGOUT' };
|
|
239
|
+
|
|
240
|
+
const auth = createMachine<
|
|
241
|
+
{ user: User | null; error: string | null },
|
|
242
|
+
'idle' | 'loading' | 'authenticated',
|
|
243
|
+
AuthEvent
|
|
244
|
+
>({
|
|
245
|
+
id: 'auth',
|
|
246
|
+
initial: 'idle',
|
|
247
|
+
context: { user: null, error: null },
|
|
248
|
+
states: {
|
|
249
|
+
// States are type-checked
|
|
250
|
+
idle: {
|
|
251
|
+
on: {
|
|
252
|
+
// Events are type-checked
|
|
253
|
+
LOGIN: 'loading',
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
loading: {
|
|
257
|
+
on: {
|
|
258
|
+
SUCCESS: {
|
|
259
|
+
target: 'authenticated',
|
|
260
|
+
// event.user is typed as User
|
|
261
|
+
action: (ctx, event) => ({ user: event.user }),
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
authenticated: {
|
|
266
|
+
on: { LOGOUT: 'idle' },
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
auth.matches('idle'); // ✓ type-checked
|
|
272
|
+
auth.matches('invalid'); // ✗ TypeScript error
|
|
273
|
+
auth.send('LOGOUT'); // ✓ type-checked
|
|
274
|
+
auth.send('INVALID'); // ✗ TypeScript error
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Svelte 5 Usage
|
|
278
|
+
|
|
279
|
+
```svelte
|
|
280
|
+
<script lang="ts">
|
|
281
|
+
import { observe, createMachine } from 'svoose';
|
|
282
|
+
import { onMount, onDestroy } from 'svelte';
|
|
283
|
+
|
|
284
|
+
// Start observing
|
|
285
|
+
let cleanup: (() => void) | null = null;
|
|
286
|
+
|
|
287
|
+
onMount(() => {
|
|
288
|
+
cleanup = observe({ endpoint: '/api/metrics' });
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
onDestroy(() => cleanup?.());
|
|
292
|
+
|
|
293
|
+
// State machine
|
|
294
|
+
const toggle = createMachine({
|
|
295
|
+
id: 'toggle',
|
|
296
|
+
initial: 'off',
|
|
297
|
+
states: {
|
|
298
|
+
off: { on: { TOGGLE: 'on' } },
|
|
299
|
+
on: { on: { TOGGLE: 'off' } },
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
</script>
|
|
303
|
+
|
|
304
|
+
<button onclick={() => toggle.send('TOGGLE')}>
|
|
305
|
+
{toggle.state}
|
|
306
|
+
</button>
|
|
307
|
+
|
|
308
|
+
{#if toggle.matches('on')}
|
|
309
|
+
<p>Light is on!</p>
|
|
310
|
+
{/if}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Roadmap
|
|
314
|
+
|
|
315
|
+
- **v0.2** — `invoke()`, `spawn()`, `after()` (delayed transitions)
|
|
316
|
+
- **v0.3** — Parallel states, history states, devtools
|
|
317
|
+
- **v0.4** — svelte-reactor integration, SvelteKit hooks
|
|
318
|
+
|
|
319
|
+
## License
|
|
320
|
+
|
|
321
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🪿 svoose - Observability + State Machines for Svelte 5
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { observe } from './observe/index.js';
|
|
7
|
+
export type { ObserveOptions } from './observe/index.js';
|
|
8
|
+
export { observeErrors, registerMachineContext, unregisterMachineContext, } from './observe/index.js';
|
|
9
|
+
export type { ObserveErrorEvent, ErrorEvent, UnhandledRejectionEvent, } from './observe/index.js';
|
|
10
|
+
export { observeCLS, observeLCP, observeFID, observeINP, observeFCP, observeTTFB, vitalObservers, } from './observe/index.js';
|
|
11
|
+
export type { Metric, MetricName, MetricRating } from './observe/index.js';
|
|
12
|
+
export { createFetchTransport, createConsoleTransport } from './transport/index.js';
|
|
13
|
+
export type { Transport, TransportOptions } from './transport/index.js';
|
|
14
|
+
export { createMachine, createEvent } from './machine/index.js';
|
|
15
|
+
export type { MachineConfig, Machine, EventObject, StateNode, TransitionConfig, InferStates, InferEvents, InferContext, } from './machine/index.js';
|
|
16
|
+
export type { VitalEvent, TransitionEvent, ObserveEvent, } from './types/index.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKzD,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,iBAAiB,EACjB,UAAU,EACV,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EACL,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAK3E,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACpF,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKxE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,aAAa,EACb,OAAO,EACP,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,oBAAoB,CAAC;AAK5B,YAAY,EACV,UAAU,EACV,eAAe,EACf,YAAY,GACb,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{observe as t}from"./observe/index.js";import{observeErrors as n,registerMachineContext as s,unregisterMachineContext as i}from"./observe/index.js";import{observeCLS as v,observeLCP as a,observeFID as x,observeINP as b,observeFCP as c,observeTTFB as f,vitalObservers as m}from"./observe/index.js";import{createFetchTransport as d,createConsoleTransport as C}from"./transport/index.js";import{createMachine as j,createEvent as M}from"./machine/index.js";export{C as createConsoleTransport,M as createEvent,d as createFetchTransport,j as createMachine,t as observe,v as observeCLS,n as observeErrors,c as observeFCP,x as observeFID,b as observeINP,a as observeLCP,f as observeTTFB,s as registerMachineContext,i as unregisterMachineContext,m as vitalObservers};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * \uD83E\uDEBF svoose - Observability + State Machines for Svelte 5\n *\n * @packageDocumentation\n */\n\n// ============================================\n// Core Observability\n// ============================================\nexport { observe } from './observe/index.js';\nexport type { ObserveOptions } from './observe/index.js';\n\n// ============================================\n// Error Tracking\n// ============================================\nexport {\n observeErrors,\n registerMachineContext,\n unregisterMachineContext,\n} from './observe/index.js';\nexport type {\n ObserveErrorEvent,\n ErrorEvent,\n UnhandledRejectionEvent,\n} from './observe/index.js';\n\n// ============================================\n// Web Vitals\n// ============================================\nexport {\n observeCLS,\n observeLCP,\n observeFID,\n observeINP,\n observeFCP,\n observeTTFB,\n vitalObservers,\n} from './observe/index.js';\nexport type { Metric, MetricName, MetricRating } from './observe/index.js';\n\n// ============================================\n// Transport\n// ============================================\nexport { createFetchTransport, createConsoleTransport } from './transport/index.js';\nexport type { Transport, TransportOptions } from './transport/index.js';\n\n// ============================================\n// State Machines\n// ============================================\nexport { createMachine, createEvent } from './machine/index.js';\nexport type {\n MachineConfig,\n Machine,\n EventObject,\n StateNode,\n TransitionConfig,\n InferStates,\n InferEvents,\n InferContext,\n} from './machine/index.js';\n\n// ============================================\n// Shared Types\n// ============================================\nexport type {\n VitalEvent,\n TransitionEvent,\n ObserveEvent,\n} from './types/index.js';\n"],
|
|
5
|
+
"mappings": "AASA,OAAS,WAAAA,MAAe,qBAMxB,OACE,iBAAAC,EACA,0BAAAC,EACA,4BAAAC,MACK,qBAUP,OACE,cAAAC,EACA,cAAAC,EACA,cAAAC,EACA,cAAAC,EACA,cAAAC,EACA,eAAAC,EACA,kBAAAC,MACK,qBAMP,OAAS,wBAAAC,EAAsB,0BAAAC,MAA8B,uBAM7D,OAAS,iBAAAC,EAAe,eAAAC,MAAmB",
|
|
6
|
+
"names": ["observe", "observeErrors", "registerMachineContext", "unregisterMachineContext", "observeCLS", "observeLCP", "observeFID", "observeINP", "observeFCP", "observeTTFB", "vitalObservers", "createFetchTransport", "createConsoleTransport", "createMachine", "createEvent"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine module exports
|
|
3
|
+
*/
|
|
4
|
+
export { createMachine } from './machine.svelte.js';
|
|
5
|
+
export type { MachineConfig, Machine, EventObject, StateNode, TransitionConfig, InferStates, InferEvents, InferContext, } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Helper to create typed events
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const loginEvent = createEvent('LOGIN', { email: 'test@example.com' });
|
|
11
|
+
*/
|
|
12
|
+
export declare function createEvent<T extends string>(type: T): {
|
|
13
|
+
type: T;
|
|
14
|
+
};
|
|
15
|
+
export declare function createEvent<T extends string, P extends object>(type: T, payload: P): {
|
|
16
|
+
type: T;
|
|
17
|
+
} & P;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/machine/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,aAAa,EACb,OAAO,EACP,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AAMpB;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AACpE,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,EAC5D,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,GACT;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/machine/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Machine module exports\n */\n\nexport { createMachine } from './machine.svelte.js';\nexport type {\n MachineConfig,\n Machine,\n EventObject,\n StateNode,\n TransitionConfig,\n InferStates,\n InferEvents,\n InferContext,\n} from './types.js';\n\n// ============================================\n// Helper: createEvent\n// ============================================\n\n/**\n * Helper to create typed events\n *\n * @example\n * const loginEvent = createEvent('LOGIN', { email: 'test@example.com' });\n */\nexport function createEvent<T extends string>(type: T): { type: T };\nexport function createEvent<T extends string, P extends object>(\n type: T,\n payload: P\n): { type: T } & P;\nexport function createEvent(type: string, payload?: object) {\n return payload ? { type, ...payload } : { type };\n}\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,iBAAAA,MAAqB,sBA2BvB,SAASC,EAAYC,EAAcC,EAAkB,CAC1D,OAAOA,EAAU,CAAE,KAAAD,EAAM,GAAGC,CAAQ,EAAI,CAAE,KAAAD,CAAK,CACjD",
|
|
6
|
+
"names": ["createMachine", "createEvent", "type", "payload"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal FSM with Svelte 5 Runes support
|
|
3
|
+
*
|
|
4
|
+
* Note: When used with Svelte 5, state and context are reactive via $state.
|
|
5
|
+
* When used outside Svelte, they work as regular properties.
|
|
6
|
+
*/
|
|
7
|
+
import type { EventObject, MachineConfig, Machine } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create a state machine
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const toggle = createMachine({
|
|
13
|
+
* id: 'toggle',
|
|
14
|
+
* initial: 'off',
|
|
15
|
+
* states: {
|
|
16
|
+
* off: { on: { TOGGLE: 'on' } },
|
|
17
|
+
* on: { on: { TOGGLE: 'off' } },
|
|
18
|
+
* },
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* toggle.send('TOGGLE');
|
|
22
|
+
* console.log(toggle.state); // 'on'
|
|
23
|
+
*/
|
|
24
|
+
export declare function createMachine<TContext extends object, TState extends string, TEvent extends EventObject>(config: MachineConfig<TContext, TState, TEvent>): Machine<TContext, TState, TEvent>;
|
|
25
|
+
export type { MachineConfig, Machine, EventObject, StateNode, TransitionConfig } from './types.js';
|
|
26
|
+
//# sourceMappingURL=machine.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machine.svelte.d.ts","sourceRoot":"","sources":["../../src/machine/machine.svelte.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,OAAO,EAGR,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,SAAS,MAAM,EACvB,MAAM,SAAS,MAAM,EACrB,MAAM,SAAS,WAAW,EAC1B,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAuKpF;AAGD,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{registerMachineContext as b,unregisterMachineContext as C}from"../observe/errors.js";import{getGlobalObserver as S}from"../observe/observe.svelte.js";function j(e){let o=e.initial,n=e.context?{...e.context}:{};const T=e.observe===!0?{transitions:!0,context:!1}:e.observe===!1||e.observe===void 0?{transitions:!1,context:!1}:e.observe;b(e.id,()=>o);const c=e.states[e.initial];if(c?.entry){const t=c.entry(n);t&&Object.assign(n,t)}function f(t,i){return t.on?.[i]}function u(t){const i=e.states[o];if(!i?.on)return!1;const r=f(i,t);return r?typeof r=="string"?!0:r.guard?r.guard(n,{type:t}):!0:!1}function y(t){const i=typeof t=="string"?{type:t}:t,r=e.states[o];if(!r?.on)return;const a=f(r,i.type);if(!a)return;const d=typeof a=="string"?a:a.target;if(typeof a=="object"&&a.guard&&!a.guard(n,i))return;const x=o;if(r.exit&&r.exit(n),typeof a=="object"&&a.action){const s=a.action(n,i);s&&Object.assign(n,s)}o=d;const p=e.states[o];if(p?.entry){const s=p.entry(n);s&&Object.assign(n,s)}if(T.transitions){const s=S();if(s){const E={type:"transition",machineId:e.id,from:x,to:o,event:i.type,timestamp:Date.now(),...T.context?{context:{...n}}:{}};s(E)}}}function v(){C(e.id)}return{get state(){return o},get context(){return n},matches(t){return o===t},matchesAny(...t){return t.includes(o)},can(t){return u(t)},send:y,destroy:v}}export{j as createMachine};
|
|
2
|
+
//# sourceMappingURL=machine.svelte.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/machine/machine.svelte.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Minimal FSM with Svelte 5 Runes support\n *\n * Note: When used with Svelte 5, state and context are reactive via $state.\n * When used outside Svelte, they work as regular properties.\n */\n\nimport { registerMachineContext, unregisterMachineContext } from '../observe/errors.js';\nimport { getGlobalObserver } from '../observe/observe.svelte.js';\nimport type {\n EventObject,\n MachineConfig,\n Machine,\n StateNode,\n TransitionConfig,\n} from './types.js';\nimport type { TransitionEvent } from '../types/index.js';\n\n/**\n * Create a state machine\n *\n * @example\n * const toggle = createMachine({\n * id: 'toggle',\n * initial: 'off',\n * states: {\n * off: { on: { TOGGLE: 'on' } },\n * on: { on: { TOGGLE: 'off' } },\n * },\n * });\n *\n * toggle.send('TOGGLE');\n * console.log(toggle.state); // 'on'\n */\nexport function createMachine<\n TContext extends object,\n TState extends string,\n TEvent extends EventObject\n>(config: MachineConfig<TContext, TState, TEvent>): Machine<TContext, TState, TEvent> {\n // Internal state - in Svelte 5 .svelte.ts files, these become reactive\n let _state: TState = config.initial;\n let _context: TContext = config.context ? { ...config.context } : ({} as TContext);\n\n // Parse observe config\n const observeConfig =\n config.observe === true\n ? { transitions: true, context: false }\n : config.observe === false || config.observe === undefined\n ? { transitions: false, context: false }\n : config.observe;\n\n // Register for error context tracking\n registerMachineContext(config.id, () => _state);\n\n // Run entry action for initial state\n const initialState = config.states[config.initial];\n if (initialState?.entry) {\n const update = initialState.entry(_context);\n if (update) {\n Object.assign(_context, update);\n }\n }\n\n /**\n * Get transition config for an event\n */\n function getTransition(\n stateConfig: StateNode<TContext, TState, TEvent>,\n eventType: TEvent['type']\n ): TransitionConfig<TContext, TState, TEvent> | TState | undefined {\n return stateConfig.on?.[eventType as keyof typeof stateConfig.on] as\n | TransitionConfig<TContext, TState, TEvent>\n | TState\n | undefined;\n }\n\n /**\n * Check if a transition is valid (exists and guard passes)\n */\n function canTransition(eventType: TEvent['type']): boolean {\n const stateConfig = config.states[_state];\n if (!stateConfig?.on) return false;\n\n const transition = getTransition(stateConfig, eventType);\n if (!transition) return false;\n\n // If it's just a target state string, it's always valid\n if (typeof transition === 'string') return true;\n\n // If there's a guard, check it (with empty event for can() check)\n if (transition.guard) {\n return transition.guard(_context, { type: eventType } as Extract<\n TEvent,\n { type: typeof eventType }\n >);\n }\n\n return true;\n }\n\n /**\n * Send an event to the machine\n */\n function send(event: TEvent | TEvent['type']): void {\n const eventObj: TEvent =\n typeof event === 'string' ? ({ type: event } as TEvent) : event;\n\n const stateConfig = config.states[_state];\n if (!stateConfig?.on) return;\n\n const transition = getTransition(stateConfig, eventObj.type);\n if (!transition) return;\n\n const targetState: TState =\n typeof transition === 'string' ? transition : transition.target;\n\n // Check guard\n if (typeof transition === 'object' && transition.guard) {\n if (\n !transition.guard(\n _context,\n eventObj as Extract<TEvent, { type: (typeof eventObj)['type'] }>\n )\n ) {\n return;\n }\n }\n\n const prevState = _state;\n\n // Run exit action\n if (stateConfig.exit) {\n stateConfig.exit(_context);\n }\n\n // Run transition action\n if (typeof transition === 'object' && transition.action) {\n const update = transition.action(\n _context,\n eventObj as Extract<TEvent, { type: (typeof eventObj)['type'] }>\n );\n if (update) {\n Object.assign(_context, update);\n }\n }\n\n // Update state\n _state = targetState;\n\n // Run entry action for new state\n const newStateConfig = config.states[_state];\n if (newStateConfig?.entry) {\n const update = newStateConfig.entry(_context);\n if (update) {\n Object.assign(_context, update);\n }\n }\n\n // Emit observation event\n if (observeConfig.transitions) {\n const observer = getGlobalObserver();\n if (observer) {\n const transitionEvent: TransitionEvent = {\n type: 'transition',\n machineId: config.id,\n from: prevState,\n to: _state,\n event: eventObj.type,\n timestamp: Date.now(),\n ...(observeConfig.context\n ? { context: { ..._context } as Record<string, unknown> }\n : {}),\n };\n observer(transitionEvent);\n }\n }\n }\n\n /**\n * Cleanup machine\n */\n function destroy(): void {\n unregisterMachineContext(config.id);\n }\n\n // Return machine instance\n return {\n get state(): TState {\n return _state;\n },\n get context(): TContext {\n return _context;\n },\n matches(state: TState): boolean {\n return _state === state;\n },\n matchesAny(...states: TState[]): boolean {\n return states.includes(_state);\n },\n can(eventType: TEvent['type']): boolean {\n return canTransition(eventType);\n },\n send,\n destroy,\n };\n}\n\n// Re-export types\nexport type { MachineConfig, Machine, EventObject, StateNode, TransitionConfig } from './types.js';\n"],
|
|
5
|
+
"mappings": "AAOA,OAAS,0BAAAA,EAAwB,4BAAAC,MAAgC,uBACjE,OAAS,qBAAAC,MAAyB,+BA0B3B,SAASC,EAIdC,EAAoF,CAEpF,IAAIC,EAAiBD,EAAO,QACxBE,EAAqBF,EAAO,QAAU,CAAE,GAAGA,EAAO,OAAQ,EAAK,CAAC,EAGpE,MAAMG,EACJH,EAAO,UAAY,GACf,CAAE,YAAa,GAAM,QAAS,EAAM,EACpCA,EAAO,UAAY,IAASA,EAAO,UAAY,OAC7C,CAAE,YAAa,GAAO,QAAS,EAAM,EACrCA,EAAO,QAGfJ,EAAuBI,EAAO,GAAI,IAAMC,CAAM,EAG9C,MAAMG,EAAeJ,EAAO,OAAOA,EAAO,OAAO,EACjD,GAAII,GAAc,MAAO,CACvB,MAAMC,EAASD,EAAa,MAAMF,CAAQ,EACtCG,GACF,OAAO,OAAOH,EAAUG,CAAM,CAElC,CAKA,SAASC,EACPC,EACAC,EACiE,CACjE,OAAOD,EAAY,KAAKC,CAAwC,CAIlE,CAKA,SAASC,EAAcD,EAAoC,CACzD,MAAMD,EAAcP,EAAO,OAAOC,CAAM,EACxC,GAAI,CAACM,GAAa,GAAI,MAAO,GAE7B,MAAMG,EAAaJ,EAAcC,EAAaC,CAAS,EACvD,OAAKE,EAGD,OAAOA,GAAe,SAAiB,GAGvCA,EAAW,MACNA,EAAW,MAAMR,EAAU,CAAE,KAAMM,CAAU,CAGnD,EAGI,GAbiB,EAc1B,CAKA,SAASG,EAAKC,EAAsC,CAClD,MAAMC,EACJ,OAAOD,GAAU,SAAY,CAAE,KAAMA,CAAM,EAAeA,EAEtDL,EAAcP,EAAO,OAAOC,CAAM,EACxC,GAAI,CAACM,GAAa,GAAI,OAEtB,MAAMG,EAAaJ,EAAcC,EAAaM,EAAS,IAAI,EAC3D,GAAI,CAACH,EAAY,OAEjB,MAAMI,EACJ,OAAOJ,GAAe,SAAWA,EAAaA,EAAW,OAG3D,GAAI,OAAOA,GAAe,UAAYA,EAAW,OAE7C,CAACA,EAAW,MACVR,EACAW,CACF,EAEA,OAIJ,MAAME,EAAYd,EAQlB,GALIM,EAAY,MACdA,EAAY,KAAKL,CAAQ,EAIvB,OAAOQ,GAAe,UAAYA,EAAW,OAAQ,CACvD,MAAML,EAASK,EAAW,OACxBR,EACAW,CACF,EACIR,GACF,OAAO,OAAOH,EAAUG,CAAM,CAElC,CAGAJ,EAASa,EAGT,MAAME,EAAiBhB,EAAO,OAAOC,CAAM,EAC3C,GAAIe,GAAgB,MAAO,CACzB,MAAMX,EAASW,EAAe,MAAMd,CAAQ,EACxCG,GACF,OAAO,OAAOH,EAAUG,CAAM,CAElC,CAGA,GAAIF,EAAc,YAAa,CAC7B,MAAMc,EAAWnB,EAAkB,EACnC,GAAImB,EAAU,CACZ,MAAMC,EAAmC,CACvC,KAAM,aACN,UAAWlB,EAAO,GAClB,KAAMe,EACN,GAAId,EACJ,MAAOY,EAAS,KAChB,UAAW,KAAK,IAAI,EACpB,GAAIV,EAAc,QACd,CAAE,QAAS,CAAE,GAAGD,CAAS,CAA6B,EACtD,CAAC,CACP,EACAe,EAASC,CAAe,CAC1B,CACF,CACF,CAKA,SAASC,GAAgB,CACvBtB,EAAyBG,EAAO,EAAE,CACpC,CAGA,MAAO,CACL,IAAI,OAAgB,CAClB,OAAOC,CACT,EACA,IAAI,SAAoB,CACtB,OAAOC,CACT,EACA,QAAQkB,EAAwB,CAC9B,OAAOnB,IAAWmB,CACpB,EACA,cAAcC,EAA2B,CACvC,OAAOA,EAAO,SAASpB,CAAM,CAC/B,EACA,IAAIO,EAAoC,CACtC,OAAOC,EAAcD,CAAS,CAChC,EACA,KAAAG,EACA,QAAAQ,CACF,CACF",
|
|
6
|
+
"names": ["registerMachineContext", "unregisterMachineContext", "getGlobalObserver", "createMachine", "config", "_state", "_context", "observeConfig", "initialState", "update", "getTransition", "stateConfig", "eventType", "canTransition", "transition", "send", "event", "eventObj", "targetState", "prevState", "newStateConfig", "observer", "transitionEvent", "destroy", "state", "states"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Machine Types
|
|
3
|
+
*/
|
|
4
|
+
export type EventObject = {
|
|
5
|
+
type: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export type Action<TContext, TEvent extends EventObject = EventObject> = (context: TContext, event?: TEvent) => Partial<TContext> | void;
|
|
9
|
+
export interface TransitionConfig<TContext, TState extends string, TEvent extends EventObject, K extends TEvent['type'] = TEvent['type']> {
|
|
10
|
+
/** Target state */
|
|
11
|
+
target: TState;
|
|
12
|
+
/** Guard condition - transition only if returns true */
|
|
13
|
+
guard?: (context: TContext, event: Extract<TEvent, {
|
|
14
|
+
type: K;
|
|
15
|
+
}>) => boolean;
|
|
16
|
+
/** Action to run during transition */
|
|
17
|
+
action?: (context: TContext, event: Extract<TEvent, {
|
|
18
|
+
type: K;
|
|
19
|
+
}>) => Partial<TContext> | void;
|
|
20
|
+
}
|
|
21
|
+
export type Transition<TContext, TState extends string, TEvent extends EventObject, K extends TEvent['type'] = TEvent['type']> = TState | TransitionConfig<TContext, TState, TEvent, K>;
|
|
22
|
+
export interface StateNode<TContext, TState extends string, TEvent extends EventObject> {
|
|
23
|
+
/** Event handlers */
|
|
24
|
+
on?: {
|
|
25
|
+
[K in TEvent['type']]?: Transition<TContext, TState, TEvent, K>;
|
|
26
|
+
};
|
|
27
|
+
/** Action to run when entering this state */
|
|
28
|
+
entry?: Action<TContext, TEvent>;
|
|
29
|
+
/** Action to run when exiting this state */
|
|
30
|
+
exit?: Action<TContext, TEvent>;
|
|
31
|
+
}
|
|
32
|
+
export interface MachineConfig<TContext extends object, TState extends string, TEvent extends EventObject> {
|
|
33
|
+
/** Unique machine ID */
|
|
34
|
+
id: string;
|
|
35
|
+
/** Initial state */
|
|
36
|
+
initial: TState;
|
|
37
|
+
/** Initial context */
|
|
38
|
+
context?: TContext;
|
|
39
|
+
/** State definitions */
|
|
40
|
+
states: {
|
|
41
|
+
[K in TState]: StateNode<TContext, TState, TEvent>;
|
|
42
|
+
};
|
|
43
|
+
/** Observability options */
|
|
44
|
+
observe?: boolean | {
|
|
45
|
+
transitions?: boolean;
|
|
46
|
+
context?: boolean;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface Machine<TContext extends object, TState extends string, TEvent extends EventObject> {
|
|
50
|
+
/** Current state (reactive in Svelte 5) */
|
|
51
|
+
readonly state: TState;
|
|
52
|
+
/** Current context (reactive in Svelte 5) */
|
|
53
|
+
readonly context: TContext;
|
|
54
|
+
/** Check if machine is in given state */
|
|
55
|
+
matches(state: TState): boolean;
|
|
56
|
+
/** Check if machine is in any of given states */
|
|
57
|
+
matchesAny(...states: TState[]): boolean;
|
|
58
|
+
/** Check if event can be sent (has valid transition) */
|
|
59
|
+
can(eventType: TEvent['type']): boolean;
|
|
60
|
+
/** Send event to machine */
|
|
61
|
+
send(event: TEvent | TEvent['type']): void;
|
|
62
|
+
/** Cleanup machine (unregister from error tracking) */
|
|
63
|
+
destroy(): void;
|
|
64
|
+
}
|
|
65
|
+
/** Extract states from machine config */
|
|
66
|
+
export type InferStates<T> = T extends MachineConfig<object, infer S, EventObject> ? S : never;
|
|
67
|
+
/** Extract events from machine config */
|
|
68
|
+
export type InferEvents<T> = T extends MachineConfig<object, string, infer E> ? E : never;
|
|
69
|
+
/** Extract context from machine config */
|
|
70
|
+
export type InferContext<T> = T extends MachineConfig<infer C, string, EventObject> ? C : never;
|
|
71
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/machine/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error tracking - captures errors and unhandled promise rejections
|
|
3
|
+
* Integrates with state machines to include machine context in error reports
|
|
4
|
+
*/
|
|
5
|
+
import type { ErrorEvent, UnhandledRejectionEvent, ObserveErrorEvent } from '../types/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* Register a machine's context for error tracking
|
|
8
|
+
* Called internally by createMachine()
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerMachineContext(id: string, getState: () => string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Unregister a machine's context
|
|
13
|
+
* Called internally when machine is destroyed
|
|
14
|
+
*/
|
|
15
|
+
export declare function unregisterMachineContext(id: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Observe global errors and unhandled promise rejections
|
|
18
|
+
* @param callback - Called for each error event
|
|
19
|
+
* @returns Cleanup function
|
|
20
|
+
*/
|
|
21
|
+
export declare function observeErrors(callback: (event: ObserveErrorEvent) => void): () => void;
|
|
22
|
+
export type { ErrorEvent, UnhandledRejectionEvent, ObserveErrorEvent };
|
|
23
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/observe/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAKhG;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAE/E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEzD;AA4BD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAC3C,MAAM,IAAI,CAsDZ;AAED,YAAY,EAAE,UAAU,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const i=new Map;function E(e,r){i.set(e,{getState:r})}function v(e){i.delete(e)}function a(){for(const[e,r]of i)try{return{machineId:e,machineState:r.getState()}}catch{}return{}}function c(){try{return typeof location<"u"?location.href:""}catch{return""}}function g(e){if(typeof window>"u")return()=>{};const r=t=>{const n={type:"error",message:t.message||"Unknown error",stack:t.error?.stack,filename:t.filename,lineno:t.lineno,colno:t.colno,timestamp:Date.now(),url:c(),...a()};e(n)},s=t=>{const n=t.reason;let o;if(n instanceof Error)o=n.message;else if(typeof n=="string")o=n;else try{o=JSON.stringify(n)}catch{o=String(n)}const d={type:"unhandled-rejection",reason:o,timestamp:Date.now(),url:c(),...a()};e(d)};return window.addEventListener("error",r),window.addEventListener("unhandledrejection",s),()=>{window.removeEventListener("error",r),window.removeEventListener("unhandledrejection",s)}}export{g as observeErrors,E as registerMachineContext,v as unregisterMachineContext};
|
|
2
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/observe/errors.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Error tracking - captures errors and unhandled promise rejections\n * Integrates with state machines to include machine context in error reports\n */\n\nimport type { ErrorEvent, UnhandledRejectionEvent, ObserveErrorEvent } from '../types/index.js';\n\n// Global machine context registry (populated by createMachine)\nconst machineContexts = new Map<string, { getState: () => string }>();\n\n/**\n * Register a machine's context for error tracking\n * Called internally by createMachine()\n */\nexport function registerMachineContext(id: string, getState: () => string): void {\n machineContexts.set(id, { getState });\n}\n\n/**\n * Unregister a machine's context\n * Called internally when machine is destroyed\n */\nexport function unregisterMachineContext(id: string): void {\n machineContexts.delete(id);\n}\n\n/**\n * Get current machine context for error reports\n * Returns first active machine (could be enhanced for multiple)\n */\nfunction getMachineContext(): { machineId?: string; machineState?: string } {\n for (const [id, ctx] of machineContexts) {\n try {\n return { machineId: id, machineState: ctx.getState() };\n } catch {\n // Machine might be in invalid state, skip it\n }\n }\n return {};\n}\n\n/**\n * Get current URL safely\n */\nfunction getCurrentUrl(): string {\n try {\n return typeof location !== 'undefined' ? location.href : '';\n } catch {\n return '';\n }\n}\n\n/**\n * Observe global errors and unhandled promise rejections\n * @param callback - Called for each error event\n * @returns Cleanup function\n */\nexport function observeErrors(\n callback: (event: ObserveErrorEvent) => void\n): () => void {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return () => {};\n }\n\n const errorHandler = (event: globalThis.ErrorEvent) => {\n const errorEvent: ErrorEvent = {\n type: 'error',\n message: event.message || 'Unknown error',\n stack: event.error?.stack,\n filename: event.filename,\n lineno: event.lineno,\n colno: event.colno,\n timestamp: Date.now(),\n url: getCurrentUrl(),\n ...getMachineContext(),\n };\n callback(errorEvent);\n };\n\n const rejectionHandler = (event: PromiseRejectionEvent) => {\n const reason = event.reason;\n let message: string;\n\n if (reason instanceof Error) {\n message = reason.message;\n } else if (typeof reason === 'string') {\n message = reason;\n } else {\n try {\n message = JSON.stringify(reason);\n } catch {\n message = String(reason);\n }\n }\n\n const rejectionEvent: UnhandledRejectionEvent = {\n type: 'unhandled-rejection',\n reason: message,\n timestamp: Date.now(),\n url: getCurrentUrl(),\n ...getMachineContext(),\n };\n callback(rejectionEvent);\n };\n\n window.addEventListener('error', errorHandler);\n window.addEventListener('unhandledrejection', rejectionHandler);\n\n return () => {\n window.removeEventListener('error', errorHandler);\n window.removeEventListener('unhandledrejection', rejectionHandler);\n };\n}\n\nexport type { ErrorEvent, UnhandledRejectionEvent, ObserveErrorEvent };\n"],
|
|
5
|
+
"mappings": "AAQA,MAAMA,EAAkB,IAAI,IAMrB,SAASC,EAAuBC,EAAYC,EAA8B,CAC/EH,EAAgB,IAAIE,EAAI,CAAE,SAAAC,CAAS,CAAC,CACtC,CAMO,SAASC,EAAyBF,EAAkB,CACzDF,EAAgB,OAAOE,CAAE,CAC3B,CAMA,SAASG,GAAmE,CAC1E,SAAW,CAACH,EAAII,CAAG,IAAKN,EACtB,GAAI,CACF,MAAO,CAAE,UAAWE,EAAI,aAAcI,EAAI,SAAS,CAAE,CACvD,MAAQ,CAER,CAEF,MAAO,CAAC,CACV,CAKA,SAASC,GAAwB,CAC/B,GAAI,CACF,OAAO,OAAO,SAAa,IAAc,SAAS,KAAO,EAC3D,MAAQ,CACN,MAAO,EACT,CACF,CAOO,SAASC,EACdC,EACY,CAEZ,GAAI,OAAO,OAAW,IACpB,MAAO,IAAM,CAAC,EAGhB,MAAMC,EAAgBC,GAAiC,CACrD,MAAMC,EAAyB,CAC7B,KAAM,QACN,QAASD,EAAM,SAAW,gBAC1B,MAAOA,EAAM,OAAO,MACpB,SAAUA,EAAM,SAChB,OAAQA,EAAM,OACd,MAAOA,EAAM,MACb,UAAW,KAAK,IAAI,EACpB,IAAKJ,EAAc,EACnB,GAAGF,EAAkB,CACvB,EACAI,EAASG,CAAU,CACrB,EAEMC,EAAoBF,GAAiC,CACzD,MAAMG,EAASH,EAAM,OACrB,IAAII,EAEJ,GAAID,aAAkB,MACpBC,EAAUD,EAAO,gBACR,OAAOA,GAAW,SAC3BC,EAAUD,MAEV,IAAI,CACFC,EAAU,KAAK,UAAUD,CAAM,CACjC,MAAQ,CACNC,EAAU,OAAOD,CAAM,CACzB,CAGF,MAAME,EAA0C,CAC9C,KAAM,sBACN,OAAQD,EACR,UAAW,KAAK,IAAI,EACpB,IAAKR,EAAc,EACnB,GAAGF,EAAkB,CACvB,EACAI,EAASO,CAAc,CACzB,EAEA,cAAO,iBAAiB,QAASN,CAAY,EAC7C,OAAO,iBAAiB,qBAAsBG,CAAgB,EAEvD,IAAM,CACX,OAAO,oBAAoB,QAASH,CAAY,EAChD,OAAO,oBAAoB,qBAAsBG,CAAgB,CACnE,CACF",
|
|
6
|
+
"names": ["machineContexts", "registerMachineContext", "id", "getState", "unregisterMachineContext", "getMachineContext", "ctx", "getCurrentUrl", "observeErrors", "callback", "errorHandler", "event", "errorEvent", "rejectionHandler", "reason", "message", "rejectionEvent"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observe module exports
|
|
3
|
+
*/
|
|
4
|
+
export { observe, setGlobalObserver, getGlobalObserver } from './observe.svelte.js';
|
|
5
|
+
export type { ObserveOptions } from './observe.svelte.js';
|
|
6
|
+
export { observeErrors, registerMachineContext, unregisterMachineContext } from './errors.js';
|
|
7
|
+
export type { ObserveErrorEvent, ErrorEvent, UnhandledRejectionEvent } from './errors.js';
|
|
8
|
+
export { vitalObservers, observeCLS, observeLCP, observeFID, observeINP, observeFCP, observeTTFB } from './vitals.js';
|
|
9
|
+
export type { Metric, MetricName, MetricRating } from './vitals.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observe/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACpF,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC9F,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtH,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{observe as o,setGlobalObserver as t,getGlobalObserver as s}from"./observe.svelte.js";import{observeErrors as b,registerMachineContext as n,unregisterMachineContext as i}from"./errors.js";import{vitalObservers as a,observeCLS as l,observeLCP as x,observeFID as m,observeINP as c,observeFCP as f,observeTTFB as E}from"./vitals.js";export{s as getGlobalObserver,o as observe,l as observeCLS,b as observeErrors,f as observeFCP,m as observeFID,c as observeINP,x as observeLCP,E as observeTTFB,n as registerMachineContext,t as setGlobalObserver,i as unregisterMachineContext,a as vitalObservers};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/observe/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Observe module exports\n */\n\nexport { observe, setGlobalObserver, getGlobalObserver } from './observe.svelte.js';\nexport type { ObserveOptions } from './observe.svelte.js';\nexport { observeErrors, registerMachineContext, unregisterMachineContext } from './errors.js';\nexport type { ObserveErrorEvent, ErrorEvent, UnhandledRejectionEvent } from './errors.js';\nexport { vitalObservers, observeCLS, observeLCP, observeFID, observeINP, observeFCP, observeTTFB } from './vitals.js';\nexport type { Metric, MetricName, MetricRating } from './vitals.js';\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,WAAAA,EAAS,qBAAAC,EAAmB,qBAAAC,MAAyB,sBAE9D,OAAS,iBAAAC,EAAe,0BAAAC,EAAwB,4BAAAC,MAAgC,cAEhF,OAAS,kBAAAC,EAAgB,cAAAC,EAAY,cAAAC,EAAY,cAAAC,EAAY,cAAAC,EAAY,cAAAC,EAAY,eAAAC,MAAmB",
|
|
6
|
+
"names": ["observe", "setGlobalObserver", "getGlobalObserver", "observeErrors", "registerMachineContext", "unregisterMachineContext", "vitalObservers", "observeCLS", "observeLCP", "observeFID", "observeINP", "observeFCP", "observeTTFB"]
|
|
7
|
+
}
|