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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main observe() function - combines vitals, errors, and transport
|
|
3
|
+
*/
|
|
4
|
+
import type { ObserveOptions, ObserveEvent } from '../types/index.js';
|
|
5
|
+
declare let globalObserverCallback: ((event: ObserveEvent) => void) | null;
|
|
6
|
+
/**
|
|
7
|
+
* Set global observer callback for state machines
|
|
8
|
+
* Called internally to connect machines to observe()
|
|
9
|
+
*/
|
|
10
|
+
export declare function setGlobalObserver(callback: typeof globalObserverCallback): void;
|
|
11
|
+
/**
|
|
12
|
+
* Get global observer callback
|
|
13
|
+
* Used by createMachine to send transition events
|
|
14
|
+
*/
|
|
15
|
+
export declare function getGlobalObserver(): typeof globalObserverCallback;
|
|
16
|
+
/**
|
|
17
|
+
* Main observe function - starts collecting metrics and errors
|
|
18
|
+
*
|
|
19
|
+
* @param options - Configuration options
|
|
20
|
+
* @returns Cleanup function to stop observing
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Basic usage
|
|
24
|
+
* observe();
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // With options
|
|
28
|
+
* observe({
|
|
29
|
+
* endpoint: '/api/metrics',
|
|
30
|
+
* vitals: ['CLS', 'LCP', 'INP'],
|
|
31
|
+
* errors: true,
|
|
32
|
+
* debug: true,
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
35
|
+
export declare function observe(options?: ObserveOptions): () => void;
|
|
36
|
+
export type { ObserveOptions };
|
|
37
|
+
//# sourceMappingURL=observe.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observe.svelte.d.ts","sourceRoot":"","sources":["../../src/observe/observe.svelte.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAc,YAAY,EAAa,MAAM,mBAAmB,CAAC;AAc7F,QAAA,IAAI,sBAAsB,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAW,CAAC;AAE1E;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,sBAAsB,GAAG,IAAI,CAE/E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,sBAAsB,CAEjE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,IAAI,CAiIhE;AAED,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{vitalObservers as h}from"./vitals.js";import{observeErrors as m}from"./errors.js";import{createFetchTransport as O}from"../transport/fetch.js";const u={endpoint:"/api/observe",vitals:!0,errors:!0,batchSize:10,flushInterval:5e3,sampleRate:1,debug:!1};let p=null;function f(i){p=i}function T(){return p}function I(i={}){if(Math.random()>(i.sampleRate??u.sampleRate))return()=>{};const t={...u,...i},c=t.transport??O(t.endpoint),r=[],n=[];let l=null;const d=()=>{try{return typeof location<"u"?location.href:""}catch{return""}},a=e=>{t.filter&&!t.filter(e)||(t.debug&&console.log("[svoose]",e),n.push(e),n.length>=t.batchSize&&o())},o=()=>{if(n.length===0)return;const e=n.splice(0,n.length);c.send(e).catch(s=>{t.debug&&console.error("[svoose] transport error:",s)})},b=e=>{const s={type:"vital",name:e.name,value:e.value,rating:e.rating,delta:e.delta,timestamp:e.timestamp,url:d()};a(s)};if(t.vitals){const e=t.vitals===!0?["CLS","LCP","FID","INP","FCP","TTFB"]:t.vitals;for(const s of e){const v=h[s];v&&r.push(v(b))}}if(t.errors&&r.push(m(e=>{a(e)})),f(a),r.push(()=>f(null)),l=setInterval(o,t.flushInterval),r.push(()=>{l&&clearInterval(l)}),typeof document<"u"){const e=()=>{document.visibilityState==="hidden"&&o()};document.addEventListener("visibilitychange",e),r.push(()=>{document.removeEventListener("visibilitychange",e)})}if(typeof window<"u"){const e=()=>{o()};window.addEventListener("beforeunload",e),r.push(()=>{window.removeEventListener("beforeunload",e)})}return()=>{o(),r.forEach(e=>e())}}export{T as getGlobalObserver,I as observe,f as setGlobalObserver};
|
|
2
|
+
//# sourceMappingURL=observe.svelte.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/observe/observe.svelte.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Main observe() function - combines vitals, errors, and transport\n */\n\nimport { vitalObservers, type Metric, type MetricName } from './vitals.js';\nimport { observeErrors, type ObserveErrorEvent } from './errors.js';\nimport { createFetchTransport } from '../transport/fetch.js';\nimport type { ObserveOptions, VitalEvent, ObserveEvent, Transport } from '../types/index.js';\n\n// Default configuration\nconst defaults = {\n endpoint: '/api/observe',\n vitals: true as const,\n errors: true,\n batchSize: 10,\n flushInterval: 5000,\n sampleRate: 1,\n debug: false,\n} satisfies Required<Omit<ObserveOptions, 'transport' | 'filter'>>;\n\n// Global observer callback for state machines\nlet globalObserverCallback: ((event: ObserveEvent) => void) | null = null;\n\n/**\n * Set global observer callback for state machines\n * Called internally to connect machines to observe()\n */\nexport function setGlobalObserver(callback: typeof globalObserverCallback): void {\n globalObserverCallback = callback;\n}\n\n/**\n * Get global observer callback\n * Used by createMachine to send transition events\n */\nexport function getGlobalObserver(): typeof globalObserverCallback {\n return globalObserverCallback;\n}\n\n/**\n * Main observe function - starts collecting metrics and errors\n *\n * @param options - Configuration options\n * @returns Cleanup function to stop observing\n *\n * @example\n * // Basic usage\n * observe();\n *\n * @example\n * // With options\n * observe({\n * endpoint: '/api/metrics',\n * vitals: ['CLS', 'LCP', 'INP'],\n * errors: true,\n * debug: true,\n * });\n */\nexport function observe(options: ObserveOptions = {}): () => void {\n // Check sampling rate\n if (Math.random() > (options.sampleRate ?? defaults.sampleRate)) {\n return () => {};\n }\n\n const config = { ...defaults, ...options };\n const transport: Transport = config.transport ?? createFetchTransport(config.endpoint);\n\n const cleanups: (() => void)[] = [];\n const buffer: ObserveEvent[] = [];\n let flushTimer: ReturnType<typeof setInterval> | null = null;\n\n // Get current URL\n const getUrl = (): string => {\n try {\n return typeof location !== 'undefined' ? location.href : '';\n } catch {\n return '';\n }\n };\n\n // Buffer an event and potentially flush\n const bufferEvent = (event: ObserveEvent): void => {\n // Apply filter if provided\n if (config.filter && !config.filter(event)) {\n return;\n }\n\n if (config.debug) {\n console.log('[svoose]', event);\n }\n\n buffer.push(event);\n\n if (buffer.length >= config.batchSize) {\n flush();\n }\n };\n\n // Send buffered events to transport\n const flush = (): void => {\n if (buffer.length === 0) return;\n\n const events = buffer.splice(0, buffer.length);\n transport.send(events).catch((err) => {\n if (config.debug) {\n console.error('[svoose] transport error:', err);\n }\n });\n };\n\n // Convert metric to vital event\n const handleMetric = (metric: Metric): void => {\n const vitalEvent: VitalEvent = {\n type: 'vital',\n name: metric.name,\n value: metric.value,\n rating: metric.rating,\n delta: metric.delta,\n timestamp: metric.timestamp,\n url: getUrl(),\n };\n bufferEvent(vitalEvent);\n };\n\n // Setup vitals observers\n if (config.vitals) {\n const vitalsToObserve: MetricName[] =\n config.vitals === true\n ? ['CLS', 'LCP', 'FID', 'INP', 'FCP', 'TTFB']\n : config.vitals;\n\n for (const name of vitalsToObserve) {\n const observer = vitalObservers[name];\n if (observer) {\n cleanups.push(observer(handleMetric));\n }\n }\n }\n\n // Setup error observer\n if (config.errors) {\n cleanups.push(\n observeErrors((event: ObserveErrorEvent) => {\n bufferEvent(event);\n })\n );\n }\n\n // Setup global observer for state machines\n setGlobalObserver(bufferEvent);\n cleanups.push(() => setGlobalObserver(null));\n\n // Setup flush interval\n flushTimer = setInterval(flush, config.flushInterval);\n cleanups.push(() => {\n if (flushTimer) clearInterval(flushTimer);\n });\n\n // Flush on page visibility change (user navigating away)\n if (typeof document !== 'undefined') {\n const visibilityHandler = (): void => {\n if (document.visibilityState === 'hidden') {\n flush();\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n cleanups.push(() => {\n document.removeEventListener('visibilitychange', visibilityHandler);\n });\n }\n\n // Flush on beforeunload\n if (typeof window !== 'undefined') {\n const unloadHandler = (): void => {\n flush();\n };\n window.addEventListener('beforeunload', unloadHandler);\n cleanups.push(() => {\n window.removeEventListener('beforeunload', unloadHandler);\n });\n }\n\n // Return cleanup function\n return () => {\n flush();\n cleanups.forEach((fn) => fn());\n };\n}\n\nexport type { ObserveOptions };\n"],
|
|
5
|
+
"mappings": "AAIA,OAAS,kBAAAA,MAAoD,cAC7D,OAAS,iBAAAC,MAA6C,cACtD,OAAS,wBAAAC,MAA4B,wBAIrC,MAAMC,EAAW,CACf,SAAU,eACV,OAAQ,GACR,OAAQ,GACR,UAAW,GACX,cAAe,IACf,WAAY,EACZ,MAAO,EACT,EAGA,IAAIC,EAAiE,KAM9D,SAASC,EAAkBC,EAA+C,CAC/EF,EAAyBE,CAC3B,CAMO,SAASC,GAAmD,CACjE,OAAOH,CACT,CAqBO,SAASI,EAAQC,EAA0B,CAAC,EAAe,CAEhE,GAAI,KAAK,OAAO,GAAKA,EAAQ,YAAcN,EAAS,YAClD,MAAO,IAAM,CAAC,EAGhB,MAAMO,EAAS,CAAE,GAAGP,EAAU,GAAGM,CAAQ,EACnCE,EAAuBD,EAAO,WAAaR,EAAqBQ,EAAO,QAAQ,EAE/EE,EAA2B,CAAC,EAC5BC,EAAyB,CAAC,EAChC,IAAIC,EAAoD,KAGxD,MAAMC,EAAS,IAAc,CAC3B,GAAI,CACF,OAAO,OAAO,SAAa,IAAc,SAAS,KAAO,EAC3D,MAAQ,CACN,MAAO,EACT,CACF,EAGMC,EAAeC,GAA8B,CAE7CP,EAAO,QAAU,CAACA,EAAO,OAAOO,CAAK,IAIrCP,EAAO,OACT,QAAQ,IAAI,WAAYO,CAAK,EAG/BJ,EAAO,KAAKI,CAAK,EAEbJ,EAAO,QAAUH,EAAO,WAC1BQ,EAAM,EAEV,EAGMA,EAAQ,IAAY,CACxB,GAAIL,EAAO,SAAW,EAAG,OAEzB,MAAMM,EAASN,EAAO,OAAO,EAAGA,EAAO,MAAM,EAC7CF,EAAU,KAAKQ,CAAM,EAAE,MAAOC,GAAQ,CAChCV,EAAO,OACT,QAAQ,MAAM,4BAA6BU,CAAG,CAElD,CAAC,CACH,EAGMC,EAAgBC,GAAyB,CAC7C,MAAMC,EAAyB,CAC7B,KAAM,QACN,KAAMD,EAAO,KACb,MAAOA,EAAO,MACd,OAAQA,EAAO,OACf,MAAOA,EAAO,MACd,UAAWA,EAAO,UAClB,IAAKP,EAAO,CACd,EACAC,EAAYO,CAAU,CACxB,EAGA,GAAIb,EAAO,OAAQ,CACjB,MAAMc,EACJd,EAAO,SAAW,GACd,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAM,EAC1CA,EAAO,OAEb,UAAWe,KAAQD,EAAiB,CAClC,MAAME,EAAW1B,EAAeyB,CAAI,EAChCC,GACFd,EAAS,KAAKc,EAASL,CAAY,CAAC,CAExC,CACF,CAsBA,GAnBIX,EAAO,QACTE,EAAS,KACPX,EAAegB,GAA6B,CAC1CD,EAAYC,CAAK,CACnB,CAAC,CACH,EAIFZ,EAAkBW,CAAW,EAC7BJ,EAAS,KAAK,IAAMP,EAAkB,IAAI,CAAC,EAG3CS,EAAa,YAAYI,EAAOR,EAAO,aAAa,EACpDE,EAAS,KAAK,IAAM,CACdE,GAAY,cAAcA,CAAU,CAC1C,CAAC,EAGG,OAAO,SAAa,IAAa,CACnC,MAAMa,EAAoB,IAAY,CAChC,SAAS,kBAAoB,UAC/BT,EAAM,CAEV,EACA,SAAS,iBAAiB,mBAAoBS,CAAiB,EAC/Df,EAAS,KAAK,IAAM,CAClB,SAAS,oBAAoB,mBAAoBe,CAAiB,CACpE,CAAC,CACH,CAGA,GAAI,OAAO,OAAW,IAAa,CACjC,MAAMC,EAAgB,IAAY,CAChCV,EAAM,CACR,EACA,OAAO,iBAAiB,eAAgBU,CAAa,EACrDhB,EAAS,KAAK,IAAM,CAClB,OAAO,oBAAoB,eAAgBgB,CAAa,CAC1D,CAAC,CACH,CAGA,MAAO,IAAM,CACXV,EAAM,EACNN,EAAS,QAASiB,GAAOA,EAAG,CAAC,CAC/B,CACF",
|
|
6
|
+
"names": ["vitalObservers", "observeErrors", "createFetchTransport", "defaults", "globalObserverCallback", "setGlobalObserver", "callback", "getGlobalObserver", "observe", "options", "config", "transport", "cleanups", "buffer", "flushTimer", "getUrl", "bufferEvent", "event", "flush", "events", "err", "handleMetric", "metric", "vitalEvent", "vitalsToObserve", "name", "observer", "visibilityHandler", "unloadHandler", "fn"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Vitals collection - NO external dependencies
|
|
3
|
+
* Uses PerformanceObserver API directly
|
|
4
|
+
*/
|
|
5
|
+
import type { MetricName, MetricRating, Metric } from '../types/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* CLS - Cumulative Layout Shift
|
|
8
|
+
* Measures visual stability
|
|
9
|
+
*/
|
|
10
|
+
export declare function observeCLS(callback: (metric: Metric) => void): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* LCP - Largest Contentful Paint
|
|
13
|
+
* Measures loading performance
|
|
14
|
+
*/
|
|
15
|
+
export declare function observeLCP(callback: (metric: Metric) => void): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* FID - First Input Delay
|
|
18
|
+
* Measures interactivity (deprecated in favor of INP)
|
|
19
|
+
*/
|
|
20
|
+
export declare function observeFID(callback: (metric: Metric) => void): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* INP - Interaction to Next Paint
|
|
23
|
+
* Measures responsiveness (replaced FID as Core Web Vital)
|
|
24
|
+
*/
|
|
25
|
+
export declare function observeINP(callback: (metric: Metric) => void): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* FCP - First Contentful Paint
|
|
28
|
+
* Measures when first content is painted
|
|
29
|
+
*/
|
|
30
|
+
export declare function observeFCP(callback: (metric: Metric) => void): () => void;
|
|
31
|
+
/**
|
|
32
|
+
* TTFB - Time to First Byte
|
|
33
|
+
* Measures server response time
|
|
34
|
+
*/
|
|
35
|
+
export declare function observeTTFB(callback: (metric: Metric) => void): () => void;
|
|
36
|
+
export declare const vitalObservers: {
|
|
37
|
+
readonly CLS: typeof observeCLS;
|
|
38
|
+
readonly LCP: typeof observeLCP;
|
|
39
|
+
readonly FID: typeof observeFID;
|
|
40
|
+
readonly INP: typeof observeINP;
|
|
41
|
+
readonly FCP: typeof observeFCP;
|
|
42
|
+
readonly TTFB: typeof observeTTFB;
|
|
43
|
+
};
|
|
44
|
+
export type { Metric, MetricName, MetricRating };
|
|
45
|
+
//# sourceMappingURL=vitals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitals.d.ts","sourceRoot":"","sources":["../../src/observe/vitals.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA2C1E;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAmBzE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAkBzE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAazE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAmBzE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAczE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAa1E;AASD,eAAO,MAAM,cAAc;;;;;;;CAOjB,CAAC;AAEX,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const f={CLS:[.1,.25],LCP:[2500,4e3],FID:[100,300],INP:[200,500],FCP:[1800,3e3],TTFB:[800,1800]};function u(r,e){const[n,t]=f[r];return e<=n?"good":e<=t?"needs-improvement":"poor"}function s(r,e,n=0){return{name:r,value:e,rating:u(r,e),delta:e-n,timestamp:Date.now()}}function c(r){if(typeof PerformanceObserver>"u")return!1;try{return PerformanceObserver.supportedEntryTypes?.includes(r)??!1}catch{return!1}}function v(r){if(!c("layout-shift"))return()=>{};let e=0,n=0;const t=new PerformanceObserver(o=>{for(const i of o.getEntries())i.hadRecentInput||(e+=i.value);r(s("CLS",e,n)),n=e});return t.observe({type:"layout-shift",buffered:!0}),()=>t.disconnect()}function d(r){if(!c("largest-contentful-paint"))return()=>{};let e=0;const n=new PerformanceObserver(t=>{const o=t.getEntries(),i=o[o.length-1];if(i){const a=i.startTime;r(s("LCP",a,e)),e=a}});return n.observe({type:"largest-contentful-paint",buffered:!0}),()=>n.disconnect()}function m(r){if(!c("first-input"))return()=>{};const e=new PerformanceObserver(n=>{const t=n.getEntries()[0];if(t){const o=t.processingStart-t.startTime;r(s("FID",o))}});return e.observe({type:"first-input",buffered:!0}),()=>e.disconnect()}function p(r){if(!c("event"))return()=>{};let e=0,n=0;const t=new PerformanceObserver(o=>{for(const i of o.getEntries()){const a=i.duration;a>e&&(e=a,r(s("INP",e,n)),n=e)}});return t.observe({type:"event",buffered:!0}),()=>t.disconnect()}function b(r){if(!c("paint"))return()=>{};const e=new PerformanceObserver(n=>{for(const t of n.getEntries())t.name==="first-contentful-paint"&&(r(s("FCP",t.startTime)),e.disconnect())});return e.observe({type:"paint",buffered:!0}),()=>e.disconnect()}function l(r){if(!c("navigation"))return()=>{};const e=new PerformanceObserver(n=>{const t=n.getEntries()[0];if(t){const o=t.responseStart-t.requestStart;r(s("TTFB",o))}});return e.observe({type:"navigation",buffered:!0}),()=>e.disconnect()}const y={CLS:v,LCP:d,FID:m,INP:p,FCP:b,TTFB:l};export{v as observeCLS,b as observeFCP,m as observeFID,p as observeINP,d as observeLCP,l as observeTTFB,y as vitalObservers};
|
|
2
|
+
//# sourceMappingURL=vitals.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/observe/vitals.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Web Vitals collection - NO external dependencies\n * Uses PerformanceObserver API directly\n */\n\nimport type { MetricName, MetricRating, Metric } from '../types/index.js';\n\n// Google's official thresholds\nconst THRESHOLDS: Record<MetricName, [number, number]> = {\n CLS: [0.1, 0.25],\n LCP: [2500, 4000],\n FID: [100, 300],\n INP: [200, 500],\n FCP: [1800, 3000],\n TTFB: [800, 1800],\n};\n\nfunction getRating(name: MetricName, value: number): MetricRating {\n const [good, poor] = THRESHOLDS[name];\n if (value <= good) return 'good';\n if (value <= poor) return 'needs-improvement';\n return 'poor';\n}\n\nfunction createMetric(\n name: MetricName,\n value: number,\n prevValue: number = 0\n): Metric {\n return {\n name,\n value,\n rating: getRating(name, value),\n delta: value - prevValue,\n timestamp: Date.now(),\n };\n}\n\n// Check if PerformanceObserver supports given entry type\nfunction isSupported(type: string): boolean {\n if (typeof PerformanceObserver === 'undefined') return false;\n try {\n return PerformanceObserver.supportedEntryTypes?.includes(type) ?? false;\n } catch {\n return false;\n }\n}\n\n/**\n * CLS - Cumulative Layout Shift\n * Measures visual stability\n */\nexport function observeCLS(callback: (metric: Metric) => void): () => void {\n if (!isSupported('layout-shift')) return () => {};\n\n let clsValue = 0;\n let prevValue = 0;\n\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n // Only count shifts without recent user input\n if (!(entry as LayoutShiftEntry).hadRecentInput) {\n clsValue += (entry as LayoutShiftEntry).value;\n }\n }\n callback(createMetric('CLS', clsValue, prevValue));\n prevValue = clsValue;\n });\n\n observer.observe({ type: 'layout-shift', buffered: true });\n return () => observer.disconnect();\n}\n\n/**\n * LCP - Largest Contentful Paint\n * Measures loading performance\n */\nexport function observeLCP(callback: (metric: Metric) => void): () => void {\n if (!isSupported('largest-contentful-paint')) return () => {};\n\n let prevValue = 0;\n\n const observer = new PerformanceObserver((list) => {\n const entries = list.getEntries();\n // LCP can have multiple entries, we want the last one\n const lastEntry = entries[entries.length - 1];\n if (lastEntry) {\n const value = lastEntry.startTime;\n callback(createMetric('LCP', value, prevValue));\n prevValue = value;\n }\n });\n\n observer.observe({ type: 'largest-contentful-paint', buffered: true });\n return () => observer.disconnect();\n}\n\n/**\n * FID - First Input Delay\n * Measures interactivity (deprecated in favor of INP)\n */\nexport function observeFID(callback: (metric: Metric) => void): () => void {\n if (!isSupported('first-input')) return () => {};\n\n const observer = new PerformanceObserver((list) => {\n const entry = list.getEntries()[0] as PerformanceEventTiming | undefined;\n if (entry) {\n const value = entry.processingStart - entry.startTime;\n callback(createMetric('FID', value));\n }\n });\n\n observer.observe({ type: 'first-input', buffered: true });\n return () => observer.disconnect();\n}\n\n/**\n * INP - Interaction to Next Paint\n * Measures responsiveness (replaced FID as Core Web Vital)\n */\nexport function observeINP(callback: (metric: Metric) => void): () => void {\n if (!isSupported('event')) return () => {};\n\n let maxINP = 0;\n let prevValue = 0;\n\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n const duration = (entry as PerformanceEventTiming).duration;\n if (duration > maxINP) {\n maxINP = duration;\n callback(createMetric('INP', maxINP, prevValue));\n prevValue = maxINP;\n }\n }\n });\n\n observer.observe({ type: 'event', buffered: true });\n return () => observer.disconnect();\n}\n\n/**\n * FCP - First Contentful Paint\n * Measures when first content is painted\n */\nexport function observeFCP(callback: (metric: Metric) => void): () => void {\n if (!isSupported('paint')) return () => {};\n\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (entry.name === 'first-contentful-paint') {\n callback(createMetric('FCP', entry.startTime));\n observer.disconnect();\n }\n }\n });\n\n observer.observe({ type: 'paint', buffered: true });\n return () => observer.disconnect();\n}\n\n/**\n * TTFB - Time to First Byte\n * Measures server response time\n */\nexport function observeTTFB(callback: (metric: Metric) => void): () => void {\n if (!isSupported('navigation')) return () => {};\n\n const observer = new PerformanceObserver((list) => {\n const entry = list.getEntries()[0] as PerformanceNavigationTiming | undefined;\n if (entry) {\n const value = entry.responseStart - entry.requestStart;\n callback(createMetric('TTFB', value));\n }\n });\n\n observer.observe({ type: 'navigation', buffered: true });\n return () => observer.disconnect();\n}\n\n// Type for layout-shift entries (not in standard lib)\ninterface LayoutShiftEntry extends PerformanceEntry {\n value: number;\n hadRecentInput: boolean;\n}\n\n// Export observer map for easy access\nexport const vitalObservers = {\n CLS: observeCLS,\n LCP: observeLCP,\n FID: observeFID,\n INP: observeINP,\n FCP: observeFCP,\n TTFB: observeTTFB,\n} as const;\n\nexport type { Metric, MetricName, MetricRating };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["THRESHOLDS", "getRating", "name", "value", "good", "poor", "createMetric", "prevValue", "isSupported", "type", "observeCLS", "callback", "clsValue", "observer", "list", "entry", "observeLCP", "entries", "lastEntry", "observeFID", "observeINP", "maxINP", "duration", "observeFCP", "observeTTFB", "vitalObservers"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch-based transport with sendBeacon fallback
|
|
3
|
+
*/
|
|
4
|
+
import type { Transport, TransportOptions } from './transport.js';
|
|
5
|
+
/**
|
|
6
|
+
* Create a fetch-based transport
|
|
7
|
+
* Uses sendBeacon for page unload, fetch otherwise
|
|
8
|
+
*
|
|
9
|
+
* @param endpoint - URL to send events to
|
|
10
|
+
* @param options - Transport options (headers, error callback)
|
|
11
|
+
*/
|
|
12
|
+
export declare function createFetchTransport(endpoint: string, options?: TransportOptions): Transport;
|
|
13
|
+
/**
|
|
14
|
+
* Create a console transport for development/debugging
|
|
15
|
+
*/
|
|
16
|
+
export declare function createConsoleTransport(options?: {
|
|
17
|
+
pretty?: boolean;
|
|
18
|
+
}): Transport;
|
|
19
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/transport/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,SAAS,CAwCX;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,SAAS,CAYpF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function a(o,n={}){return{async send(e){if(e.length!==0)try{const r=JSON.stringify(e);if(typeof document<"u"&&document.visibilityState==="hidden"&&typeof navigator<"u"&&navigator.sendBeacon){const t=new Blob([r],{type:"application/json"});if(!navigator.sendBeacon(o,t))throw new Error("sendBeacon failed");return}await fetch(o,{method:"POST",headers:{"Content-Type":"application/json",...n.headers},body:r,keepalive:!0})}catch(r){n.onError?.(r)}}}}function i(o={}){return{async send(n){for(const e of n)o.pretty?console.log("[svoose]",JSON.stringify(e,null,2)):console.log("[svoose]",e)}}}export{i as createConsoleTransport,a as createFetchTransport};
|
|
2
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/transport/fetch.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Fetch-based transport with sendBeacon fallback\n */\n\nimport type { Transport, TransportOptions } from './transport.js';\n\n/**\n * Create a fetch-based transport\n * Uses sendBeacon for page unload, fetch otherwise\n *\n * @param endpoint - URL to send events to\n * @param options - Transport options (headers, error callback)\n */\nexport function createFetchTransport(\n endpoint: string,\n options: TransportOptions = {}\n): Transport {\n return {\n async send(events) {\n if (events.length === 0) return;\n\n try {\n const payload = JSON.stringify(events);\n\n // Use sendBeacon when page is hidden (e.g., user navigating away)\n // sendBeacon is more reliable for unload scenarios\n if (\n typeof document !== 'undefined' &&\n document.visibilityState === 'hidden' &&\n typeof navigator !== 'undefined' &&\n navigator.sendBeacon\n ) {\n const blob = new Blob([payload], { type: 'application/json' });\n const success = navigator.sendBeacon(endpoint, blob);\n if (!success) {\n throw new Error('sendBeacon failed');\n }\n return;\n }\n\n // Use fetch for normal operation\n await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n body: payload,\n // keepalive ensures request completes even if page is closed\n keepalive: true,\n });\n } catch (error) {\n options.onError?.(error as Error);\n }\n },\n };\n}\n\n/**\n * Create a console transport for development/debugging\n */\nexport function createConsoleTransport(options: { pretty?: boolean } = {}): Transport {\n return {\n async send(events) {\n for (const event of events) {\n if (options.pretty) {\n console.log('[svoose]', JSON.stringify(event, null, 2));\n } else {\n console.log('[svoose]', event);\n }\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAaO,SAASA,EACdC,EACAC,EAA4B,CAAC,EAClB,CACX,MAAO,CACL,MAAM,KAAKC,EAAQ,CACjB,GAAIA,EAAO,SAAW,EAEtB,GAAI,CACF,MAAMC,EAAU,KAAK,UAAUD,CAAM,EAIrC,GACE,OAAO,SAAa,KACpB,SAAS,kBAAoB,UAC7B,OAAO,UAAc,KACrB,UAAU,WACV,CACA,MAAME,EAAO,IAAI,KAAK,CAACD,CAAO,EAAG,CAAE,KAAM,kBAAmB,CAAC,EAE7D,GAAI,CADY,UAAU,WAAWH,EAAUI,CAAI,EAEjD,MAAM,IAAI,MAAM,mBAAmB,EAErC,MACF,CAGA,MAAM,MAAMJ,EAAU,CACpB,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,GAAGC,EAAQ,OACb,EACA,KAAME,EAEN,UAAW,EACb,CAAC,CACH,OAASE,EAAO,CACdJ,EAAQ,UAAUI,CAAc,CAClC,CACF,CACF,CACF,CAKO,SAASC,EAAuBL,EAAgC,CAAC,EAAc,CACpF,MAAO,CACL,MAAM,KAAKC,EAAQ,CACjB,UAAWK,KAASL,EACdD,EAAQ,OACV,QAAQ,IAAI,WAAY,KAAK,UAAUM,EAAO,KAAM,CAAC,CAAC,EAEtD,QAAQ,IAAI,WAAYA,CAAK,CAGnC,CACF,CACF",
|
|
6
|
+
"names": ["createFetchTransport", "endpoint", "options", "events", "payload", "blob", "error", "createConsoleTransport", "event"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transport/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/transport/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Transport exports\n */\n\nexport type { Transport, TransportOptions } from './transport.js';\nexport { createFetchTransport, createConsoleTransport } from './fetch.js';\n"],
|
|
5
|
+
"mappings": "AAKA,OAAS,wBAAAA,EAAsB,0BAAAC,MAA8B",
|
|
6
|
+
"names": ["createFetchTransport", "createConsoleTransport"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport interface - defines how events are sent to backend
|
|
3
|
+
*/
|
|
4
|
+
import type { ObserveEvent } from '../types/index.js';
|
|
5
|
+
export interface Transport {
|
|
6
|
+
send(events: ObserveEvent[]): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface TransportOptions {
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
onError?: (error: Error) => void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/transport/transport.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export type MetricName = 'CLS' | 'LCP' | 'FID' | 'INP' | 'FCP' | 'TTFB';
|
|
2
|
+
export type MetricRating = 'good' | 'needs-improvement' | 'poor';
|
|
3
|
+
export interface Metric {
|
|
4
|
+
name: MetricName;
|
|
5
|
+
value: number;
|
|
6
|
+
rating: MetricRating;
|
|
7
|
+
delta: number;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ErrorEvent {
|
|
11
|
+
type: 'error';
|
|
12
|
+
message: string;
|
|
13
|
+
stack?: string;
|
|
14
|
+
filename?: string;
|
|
15
|
+
lineno?: number;
|
|
16
|
+
colno?: number;
|
|
17
|
+
timestamp: number;
|
|
18
|
+
url: string;
|
|
19
|
+
machineId?: string;
|
|
20
|
+
machineState?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface UnhandledRejectionEvent {
|
|
23
|
+
type: 'unhandled-rejection';
|
|
24
|
+
reason: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
url: string;
|
|
27
|
+
machineId?: string;
|
|
28
|
+
machineState?: string;
|
|
29
|
+
}
|
|
30
|
+
export type ObserveErrorEvent = ErrorEvent | UnhandledRejectionEvent;
|
|
31
|
+
export interface VitalEvent {
|
|
32
|
+
type: 'vital';
|
|
33
|
+
name: MetricName;
|
|
34
|
+
value: number;
|
|
35
|
+
rating: MetricRating;
|
|
36
|
+
delta: number;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
url: string;
|
|
39
|
+
}
|
|
40
|
+
export interface TransitionEvent {
|
|
41
|
+
type: 'transition';
|
|
42
|
+
machineId: string;
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
event: string;
|
|
46
|
+
timestamp: number;
|
|
47
|
+
context?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
export type ObserveEvent = VitalEvent | ObserveErrorEvent | TransitionEvent;
|
|
50
|
+
export interface Transport {
|
|
51
|
+
send(events: ObserveEvent[]): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
export interface TransportOptions {
|
|
54
|
+
headers?: Record<string, string>;
|
|
55
|
+
onError?: (error: Error) => void;
|
|
56
|
+
}
|
|
57
|
+
export interface ObserveOptions {
|
|
58
|
+
/** URL endpoint for sending data */
|
|
59
|
+
endpoint?: string;
|
|
60
|
+
/** Custom transport implementation */
|
|
61
|
+
transport?: Transport;
|
|
62
|
+
/** Collect Web Vitals. true = all, array = selected */
|
|
63
|
+
vitals?: boolean | MetricName[];
|
|
64
|
+
/** Collect errors */
|
|
65
|
+
errors?: boolean;
|
|
66
|
+
/** Batch size before sending */
|
|
67
|
+
batchSize?: number;
|
|
68
|
+
/** Flush interval in ms */
|
|
69
|
+
flushInterval?: number;
|
|
70
|
+
/** Filter function for events */
|
|
71
|
+
filter?: (event: ObserveEvent) => boolean;
|
|
72
|
+
/** Sampling rate (0-1) */
|
|
73
|
+
sampleRate?: number;
|
|
74
|
+
/** Log to console */
|
|
75
|
+
debug?: boolean;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* after() - Delayed transitions (v0.2)
|
|
3
|
+
*
|
|
4
|
+
* Автоматичний перехід після затримки
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const notification = createMachine({
|
|
8
|
+
* initial: 'visible',
|
|
9
|
+
* states: {
|
|
10
|
+
* visible: {
|
|
11
|
+
* after: {
|
|
12
|
+
* 3000: 'hidden', // Перехід через 3 секунди
|
|
13
|
+
* },
|
|
14
|
+
* on: { DISMISS: 'hidden' },
|
|
15
|
+
* },
|
|
16
|
+
* hidden: {},
|
|
17
|
+
* },
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
export interface AfterConfig {
|
|
21
|
+
/** Delay in ms -> target state */
|
|
22
|
+
[delay: number]: string | {
|
|
23
|
+
target: string;
|
|
24
|
+
guard?: (context: unknown) => boolean;
|
|
25
|
+
action?: (context: unknown) => Partial<unknown> | void;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=after.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"after.d.ts","sourceRoot":"","sources":["../../src/upgrade/after.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;KACxD,CAAC;CACH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* History states (v0.3)
|
|
3
|
+
*
|
|
4
|
+
* Запам'ятовує попередній стан для повернення
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const player = createMachine({
|
|
8
|
+
* initial: 'stopped',
|
|
9
|
+
* states: {
|
|
10
|
+
* stopped: {
|
|
11
|
+
* on: { PLAY: 'playing' },
|
|
12
|
+
* },
|
|
13
|
+
* playing: {
|
|
14
|
+
* on: {
|
|
15
|
+
* PAUSE: 'paused',
|
|
16
|
+
* STOP: 'stopped',
|
|
17
|
+
* },
|
|
18
|
+
* },
|
|
19
|
+
* paused: {
|
|
20
|
+
* on: {
|
|
21
|
+
* // Повертається до попереднього стану (playing)
|
|
22
|
+
* RESUME: { target: 'playing.history' },
|
|
23
|
+
* STOP: 'stopped',
|
|
24
|
+
* },
|
|
25
|
+
* },
|
|
26
|
+
* },
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
export type HistoryType = 'shallow' | 'deep';
|
|
30
|
+
export interface HistoryStateConfig {
|
|
31
|
+
type: 'history';
|
|
32
|
+
history: HistoryType;
|
|
33
|
+
/** Default state if no history */
|
|
34
|
+
target?: string;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/upgrade/history.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,WAAW,CAAC;IACrB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🪿 svoose/upgrade - Future features
|
|
3
|
+
*
|
|
4
|
+
* v0.2 - Async & Time:
|
|
5
|
+
* - invoke() - async functions/promises
|
|
6
|
+
* - spawn() - dynamic child machines
|
|
7
|
+
* - after() - delayed transitions
|
|
8
|
+
*
|
|
9
|
+
* v0.3 - Advanced States:
|
|
10
|
+
* - Parallel states
|
|
11
|
+
* - History states
|
|
12
|
+
* - Devtools
|
|
13
|
+
*
|
|
14
|
+
* v0.4 - Integration:
|
|
15
|
+
* - @svoose/reactor - svelte-reactor integration
|
|
16
|
+
* (persist, middleware, sync, etc.)
|
|
17
|
+
* - @svoose/sveltekit - SvelteKit hooks
|
|
18
|
+
*/
|
|
19
|
+
export declare const UPGRADE_VERSION = "0.2.0";
|
|
20
|
+
export type { InvokeConfig } from './invoke.js';
|
|
21
|
+
export type { SpawnOptions, SpawnedMachine } from './spawn.js';
|
|
22
|
+
export type { AfterConfig } from './after.js';
|
|
23
|
+
export type { ParallelStateConfig } from './parallel.js';
|
|
24
|
+
export type { HistoryType, HistoryStateConfig } from './history.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upgrade/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,eAAe,UAAU,CAAC;AAGvC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* invoke() - Async service invocation (v0.2)
|
|
3
|
+
*
|
|
4
|
+
* Дозволяє викликати async функції/promises з машини станів
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const auth = createMachine({
|
|
8
|
+
* states: {
|
|
9
|
+
* loading: {
|
|
10
|
+
* invoke: {
|
|
11
|
+
* src: async (ctx) => await api.login(ctx.email),
|
|
12
|
+
* onDone: { target: 'success', action: (ctx, e) => ({ user: e.data }) },
|
|
13
|
+
* onError: { target: 'error', action: (ctx, e) => ({ error: e.message }) },
|
|
14
|
+
* },
|
|
15
|
+
* },
|
|
16
|
+
* },
|
|
17
|
+
* });
|
|
18
|
+
*/
|
|
19
|
+
export interface InvokeConfig<TContext, TData, TError = Error> {
|
|
20
|
+
/** Async function to invoke */
|
|
21
|
+
src: (context: TContext) => Promise<TData>;
|
|
22
|
+
/** Transition on success */
|
|
23
|
+
onDone?: {
|
|
24
|
+
target: string;
|
|
25
|
+
action?: (context: TContext, event: {
|
|
26
|
+
type: 'done';
|
|
27
|
+
data: TData;
|
|
28
|
+
}) => Partial<TContext> | void;
|
|
29
|
+
};
|
|
30
|
+
/** Transition on error */
|
|
31
|
+
onError?: {
|
|
32
|
+
target: string;
|
|
33
|
+
action?: (context: TContext, event: {
|
|
34
|
+
type: 'error';
|
|
35
|
+
error: TError;
|
|
36
|
+
}) => Partial<TContext> | void;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=invoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/upgrade/invoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,MAAM,WAAW,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK;IAC3D,+BAA+B;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3C,4BAA4B;IAC5B,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,KAAK,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;KAChG,CAAC;IACF,0BAA0B;IAC1B,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;YAAE,IAAI,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;KACnG,CAAC;CACH"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel states (v0.3)
|
|
3
|
+
*
|
|
4
|
+
* Дозволяє мати кілька активних станів одночасно
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const editor = createMachine({
|
|
8
|
+
* type: 'parallel',
|
|
9
|
+
* states: {
|
|
10
|
+
* text: {
|
|
11
|
+
* initial: 'idle',
|
|
12
|
+
* states: {
|
|
13
|
+
* idle: { on: { EDIT: 'editing' } },
|
|
14
|
+
* editing: { on: { SAVE: 'idle' } },
|
|
15
|
+
* },
|
|
16
|
+
* },
|
|
17
|
+
* toolbar: {
|
|
18
|
+
* initial: 'collapsed',
|
|
19
|
+
* states: {
|
|
20
|
+
* collapsed: { on: { EXPAND: 'expanded' } },
|
|
21
|
+
* expanded: { on: { COLLAPSE: 'collapsed' } },
|
|
22
|
+
* },
|
|
23
|
+
* },
|
|
24
|
+
* },
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* // editor.state = { text: 'idle', toolbar: 'collapsed' }
|
|
28
|
+
*/
|
|
29
|
+
export interface ParallelStateConfig {
|
|
30
|
+
type: 'parallel';
|
|
31
|
+
states: Record<string, {
|
|
32
|
+
initial: string;
|
|
33
|
+
states: Record<string, unknown>;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=parallel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel.d.ts","sourceRoot":"","sources":["../../src/upgrade/parallel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACjC,CAAC,CAAC;CACJ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spawn() - Dynamic child machines (v0.2)
|
|
3
|
+
*
|
|
4
|
+
* Дозволяє динамічно створювати child machines
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const parent = createMachine({
|
|
8
|
+
* context: { children: [] },
|
|
9
|
+
* states: {
|
|
10
|
+
* active: {
|
|
11
|
+
* on: {
|
|
12
|
+
* ADD_CHILD: {
|
|
13
|
+
* action: (ctx) => ({
|
|
14
|
+
* children: [...ctx.children, spawn(childMachine, { id: `child-${Date.now()}` })],
|
|
15
|
+
* }),
|
|
16
|
+
* },
|
|
17
|
+
* },
|
|
18
|
+
* },
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
export interface SpawnOptions {
|
|
23
|
+
/** Unique ID for the spawned machine */
|
|
24
|
+
id?: string;
|
|
25
|
+
/** Sync with parent (auto-cleanup) */
|
|
26
|
+
sync?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface SpawnedMachine<TContext, TState, TEvent> {
|
|
29
|
+
id: string;
|
|
30
|
+
state: TState;
|
|
31
|
+
context: TContext;
|
|
32
|
+
send: (event: TEvent) => void;
|
|
33
|
+
stop: () => void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=spawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/upgrade/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB"}
|