@asgard-js/core 0.3.84 → 0.3.86

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.
@@ -1,6 +1,6 @@
1
1
  import { EventType } from '../constants/enum';
2
2
  import { Observable, Subscription } from 'rxjs';
3
- import { ChannelMetadata, ClientConfig, IAsgardServiceClient, FetchSsePayload, FetchSseOptions, SseResponse, SseEvents, BlobUploadResponse, ChannelHomeDownloadResult, MessageFeedbackReply, MessageFeedbackRequest, SandboxChannelScope, SandboxFsCopyMoveOptions, SandboxFsCopyResult, SandboxFsListResult, SandboxFsReadOptions, SandboxFsReadResult, SandboxFsStatResult, SandboxFsWatchEvent, SandboxFsWriteOptions, SandboxFsWriteResult, StopGenerationOptions } from '../types';
3
+ import { ChannelMetadata, ClientConfig, IAsgardServiceClient, FetchSsePayload, FetchSseOptions, SseResponse, SseEvents, BlobUploadResponse, ChannelHomeDownloadResult, MessageFeedbackReply, MessageFeedbackRequest, SandboxBrowserSessionCredentials, SandboxChannelScope, SandboxFsCopyMoveOptions, SandboxFsCopyResult, SandboxFsListResult, SandboxFsReadOptions, SandboxFsReadResult, SandboxFsStatResult, SandboxFsWatchEvent, SandboxFsWriteOptions, SandboxFsWriteResult, StopGenerationOptions } from '../types';
4
4
 
5
5
  export default class AsgardServiceClient implements IAsgardServiceClient {
6
6
  private apiKey?;
@@ -124,6 +124,22 @@ export default class AsgardServiceClient implements IAsgardServiceClient {
124
124
  * 呼叫時它會被忽略,但前置 relay 用它做 ownership 證明,缺了就是 `400`。
125
125
  */
126
126
  generateSandboxBrowserOpenUrl(sandboxName: string, options?: SandboxChannelScope): Promise<string>;
127
+ /**
128
+ * F-035 — 取得 sandbox 瀏覽器的串流連線憑證:`POST {base}/sandbox/{sandboxName}/browser/session`
129
+ * → `{ wsUrl, token }`(envelope 容錯,比照 `generateSandboxBrowserOpenUrl`)。
130
+ *
131
+ * 與 `generateSandboxBrowserOpenUrl` 的差別在**誰畫畫面**:那一支拿的是一次性網址、交給新分頁載入
132
+ * Neko 自己的前端(UC-034,保留不動當 fallback);這一支拿的是 WebSocket endpoint 與 token,由 SDK
133
+ * 自己接 WebRTC、自己畫、自己轉送鍵鼠。
134
+ *
135
+ * 三件呼叫端必須知道的性質:
136
+ * - **token 是 Neko 的 session token,不是 Asgard 的。** 權限等同使用者透過舊的 open-url 流程本來就
137
+ * 能做的事,並隨 sandbox pod 一起消失。
138
+ * - **token 不在 `wsUrl` 裡**,連線時自己 append `?token=`(瀏覽器的 WebSocket API 不能設 header)。
139
+ * - **可以重複呼叫**,每次 mint 一個新 session。連線斷掉或 sandbox 重啟後就該重呼,不要留著舊 token
140
+ * 重試 —— token 沒有 TTL 但存在 Neko 的記憶體裡,pod 一重啟就失效。
141
+ */
142
+ createSandboxBrowserSession(sandboxName: string, options?: SandboxChannelScope): Promise<SandboxBrowserSessionCredentials>;
127
143
  /**
128
144
  * F-021 — 衍生 sandbox fs 端點 base:`{base}/sandbox/{sandboxName}/fs`(namespace / bot-provider 已在 base)。
129
145
  */
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * X11 keysyms for the keys that have no arithmetic rule — function keys, navigation, modifiers.
3
+ *
4
+ * Printable characters are **not** in here; they follow the two rules in `charToKeysym`. F5 and F12 are
5
+ * listed because driving a remote browser genuinely uses them.
6
+ */
7
+ export declare const KEYSYM: Readonly<Record<string, number>>;
8
+ /** The modifier keysyms the macOS remap reads and writes. Named so the mapping below is legible. */
9
+ export declare const XK: {
10
+ readonly ISO_Level3_Shift: 65027;
11
+ readonly Shift_L: 65505;
12
+ readonly Mode_switch: 65406;
13
+ readonly Control_L: 65507;
14
+ readonly Meta_L: 65511;
15
+ readonly Alt_L: 65513;
16
+ readonly Alt_R: 65514;
17
+ readonly Super_L: 65515;
18
+ readonly Super_R: 65516;
19
+ };
20
+ /**
21
+ * One character → one keysym. Two rules, no table:
22
+ *
23
+ * 1. At or below `0xFF`, the keysym *is* the code point (ASCII and Latin-1 line up by design).
24
+ * 2. Above it, `codePoint | 0x01000000`.
25
+ *
26
+ * Rule 2 is why **the remote needs no input method installed**: its `XKey()` hands an unknown keysym to
27
+ * `XkbAddKeyKeysym`, which allocates an empty keycode for it on the spot. Whether the character exists in
28
+ * the remote keyboard layout is simply not a question that gets asked.
29
+ */
30
+ export declare function charToKeysym(character: string): number;
31
+ /**
32
+ * A `KeyboardEvent.key` value → keysym, or `null` when there is no answer.
33
+ *
34
+ * Returning `null` rather than a fallback is deliberate: a guessed keysym is indistinguishable from a
35
+ * correct one until the remote does the wrong thing. Callers should surface the unmapped key (the lab page
36
+ * lists them) instead of sending something plausible.
37
+ */
38
+ export declare function keyToKeysym(key: string): number | null;
39
+ /**
40
+ * Whether a keysym denotes something that turns into text.
41
+ *
42
+ * The distinction drives routing, not display: printable characters must travel the IME text path (it is
43
+ * the only one that can handle composition), while the keysym path carries modifiers and function keys.
44
+ */
45
+ export declare function isPrintableKeysym(keysym: number): boolean;
46
+ /**
47
+ * Remap a modifier keysym for the remote's X11 expectations. Identity on every non-macOS platform.
48
+ *
49
+ * The one that matters is **⌘ (`Meta_L`) → `Control_L`**: without it, ⌘A and ⌘C do nothing at all on the
50
+ * remote, because the Chromium over there is waiting for Ctrl. The full table is copied from the upstream
51
+ * neko client, which in turn credits noVNC / RealVNC / TigerVNC — it is what this class of client does, not
52
+ * a preference.
53
+ */
54
+ export declare function mapModifierKeysym(keysym: number, macOS?: boolean): number;
55
+ /**
56
+ * Ceiling on how many X11 scroll clicks one wheel event may become.
57
+ *
58
+ * **Not a sensitivity tuning knob.** The server loops `for (i < abs(delta))` and emits one XTest event per
59
+ * iteration, so forwarding Chrome's `deltaY = 100` verbatim tells the remote to scroll one hundred times.
60
+ * 10 is the upstream default.
61
+ */
62
+ export declare const WHEEL_MAX = 10;
63
+ /** Upstream's wheel throttle window, in milliseconds. Exported so the panel throttles to the same figure. */
64
+ export declare const WHEEL_THROTTLE_MS = 100;
65
+ /** The parts of a `WheelEvent` this conversion needs. Structural, so core never names a DOM type. */
66
+ export interface WheelDelta {
67
+ deltaX: number;
68
+ deltaY: number;
69
+ /** 0 = pixels, 1 = lines, 2 = pages. */
70
+ deltaMode: number;
71
+ }
72
+ /**
73
+ * Browser wheel deltas → remote scroll deltas.
74
+ *
75
+ * **The sign flips.** A browser's `deltaY > 0` means "content moves down"; X11's positive direction is
76
+ * button 4, which is *up*. The two conventions are opposites. Upstream neko exposes this as a
77
+ * `scroll_invert` *setting*, which makes it look like taste — but its default is `true`, i.e. everybody is
78
+ * running the inverted value, because the un-inverted one is simply wrong.
79
+ */
80
+ export declare function normalizeWheel(event: WheelDelta): {
81
+ x: number;
82
+ y: number;
83
+ };
84
+ //# sourceMappingURL=keysym.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keysym.d.ts","sourceRoot":"","sources":["../../src/lib/keysym.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkC1C,CAAC;AAEX,oGAAoG;AACpG,eAAO,MAAM,EAAE;;;;;;;;;;CAUL,CAAC;AAKX;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAItD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQtD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzD;AAaD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,OAA2B,GAAG,MAAM,CAiB5F;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,6GAA6G;AAC7G,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,qGAAqG;AACrG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAO1E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=keysym.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keysym.spec.d.ts","sourceRoot":"","sources":["../../src/lib/keysym.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { SandboxBrowserSessionCredentials, SandboxBrowserTransport } from '../types/sandbox-browser';
2
+
3
+ /**
4
+ * Decode one data-channel frame into a cursor position, or `null` if it is not one.
5
+ *
6
+ * Exported for its own unit test: the frame layout is three big-endian reads at fixed offsets, and getting
7
+ * one offset wrong puts the remote cursor somewhere plausible but wrong — which looks like a rendering bug,
8
+ * not a decoding one.
9
+ */
10
+ export declare function decodeCursorFrame(data: ArrayBuffer): {
11
+ x: number;
12
+ y: number;
13
+ } | null;
14
+ /** How the transport obtains `{ wsUrl, token }`. Injected so the lab can swap in a direct Neko login. */
15
+ export type SandboxBrowserCredentialSource = (sandboxName: string) => Promise<SandboxBrowserSessionCredentials>;
16
+ export interface SandboxBrowserTransportOptions {
17
+ /** Mints connection credentials — normally `client.createSandboxBrowserSession.bind(client)`. */
18
+ createSession: SandboxBrowserCredentialSource;
19
+ /** Display name announced in `signal/answer`. Cosmetic; shows up in Neko's member list. */
20
+ displayName?: string;
21
+ }
22
+ /**
23
+ * Build a transport over the Neko protocol.
24
+ *
25
+ * Credentials are fetched per `connect()` call rather than cached, which is what makes reconnection
26
+ * correct: the token has no TTL but lives in the server's memory, so a pod restart invalidates it, and
27
+ * retrying with the old one fails in a way that looks like a network problem (spec §7.10).
28
+ */
29
+ export declare function createSandboxBrowserTransport(options: SandboxBrowserTransportOptions): SandboxBrowserTransport;
30
+ //# sourceMappingURL=sandbox-browser-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-browser-transport.d.ts","sourceRoot":"","sources":["../../src/lib/sandbox-browser-transport.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAKV,gCAAgC,EAChC,uBAAuB,EAExB,MAAM,0BAA0B,CAAC;AAyClC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAOpF;AAED,yGAAyG;AACzG,MAAM,MAAM,8BAA8B,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,gCAAgC,CAAC,CAAC;AAEhH,MAAM,WAAW,8BAA8B;IAC7C,iGAAiG;IACjG,aAAa,EAAE,8BAA8B,CAAC;IAC9C,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,8BAA8B,GAAG,uBAAuB,CA0R9G"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sandbox-browser-transport.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-browser-transport.spec.d.ts","sourceRoot":"","sources":["../../src/lib/sandbox-browser-transport.spec.ts"],"names":[],"mappings":""}
@@ -7,6 +7,7 @@ export type * from './subagent';
7
7
  export type * from './event-emitter';
8
8
  export type * from './blob';
9
9
  export type * from './sandbox-fs';
10
+ export type * from './sandbox-browser';
10
11
  export type * from './source-set-fs';
11
12
  export { HttpError, isHttpError } from './http-error';
12
13
  export { ChannelBusyError, isChannelBusyError } from './channel-busy-error';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,UAAU,CAAC;AAC9B,mBAAmB,WAAW,CAAC;AAC/B,mBAAmB,gBAAgB,CAAC;AACpC,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,YAAY,CAAC;AAChC,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,cAAc,CAAC;AAClC,mBAAmB,iBAAiB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,UAAU,CAAC;AAC9B,mBAAmB,WAAW,CAAC;AAC/B,mBAAmB,gBAAgB,CAAC;AACpC,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,YAAY,CAAC;AAChC,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,QAAQ,CAAC;AAC5B,mBAAmB,cAAc,CAAC;AAClC,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,iBAAiB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Connection credentials from `POST …/sandbox/{name}/browser/session`.
3
+ *
4
+ * The token is **Neko's** session token, not Asgard's: it grants exactly what the user could already do
5
+ * through the older open-url flow, and it dies with the sandbox pod. It is a separate field from `wsUrl`
6
+ * rather than pre-baked into it — partly because the caller has to append it as a query parameter anyway
7
+ * (browsers cannot set headers on a WebSocket), partly so the credential never ends up inside a string
8
+ * that something else might log as a URL.
9
+ */
10
+ export interface SandboxBrowserSessionCredentials {
11
+ /** The Neko WebSocket endpoint, e.g. `wss://…/api/ws`. Carries no token. */
12
+ wsUrl: string;
13
+ /** Neko session token, appended by the transport as `?token=…`. */
14
+ token: string;
15
+ }
16
+ /**
17
+ * Who currently holds the remote keyboard and mouse.
18
+ *
19
+ * The only authority is the server's `control/host` event — never a local optimistic guess. A UI that
20
+ * believes it has control when it does not is this panel's worst failure mode: the user clicks and types
21
+ * at a picture while the server silently discards everything (spec §6 — a refused `control/request`
22
+ * produces no client-visible error at all).
23
+ *
24
+ * - `me` — this session is the host.
25
+ * - `agent` — somebody else is (the agent, or another person who took over).
26
+ * - `none` — nobody holds it.
27
+ */
28
+ export type BrowserHost = 'me' | 'agent' | 'none';
29
+ /** Where the connection is. `live` means media is flowing; it does **not** mean the picture has dimensions yet. */
30
+ export type BrowserStatus = 'idle' | 'connecting' | 'live' | 'error';
31
+ /** One pointer action, already converted to remote desktop coordinates by the caller. */
32
+ export interface RemotePointerEvent {
33
+ type: 'move' | 'down' | 'up' | 'scroll';
34
+ x: number;
35
+ y: number;
36
+ /** X11 button code — 1 left, 2 middle, 3 right (= JS `button + 1`). Present for `down` / `up`. */
37
+ button?: number;
38
+ /** Normalized scroll delta (see `normalizeWheel`). Present for `scroll`. */
39
+ deltaX?: number;
40
+ deltaY?: number;
41
+ }
42
+ /**
43
+ * One key action.
44
+ *
45
+ * `down` / `up` carry a keysym the **caller** already computed, because turning a browser `KeyboardEvent`
46
+ * into an X11 keysym is notoriously hard (cross-browser differences, keyboard layouts, modifier chords)
47
+ * and is therefore delegated to Guacamole's keyboard in the react package. Core does not guess.
48
+ *
49
+ * `text` carries a string the IME already composed; the transport converts it to Unicode keysyms itself,
50
+ * which is how CJK reaches a remote desktop that has no input method installed at all.
51
+ */
52
+ export interface RemoteKeyEvent {
53
+ type: 'down' | 'up' | 'text';
54
+ /** For `down` / `up`: the X11 keysym, modifier remapping already applied. */
55
+ keysym?: number;
56
+ /** For `text`: the composed string. */
57
+ text?: string;
58
+ }
59
+ /** A remote desktop coordinate, used for the cursor the server streams over the data channel. */
60
+ export interface RemoteCursorPosition {
61
+ x: number;
62
+ y: number;
63
+ }
64
+ /** Callbacks a transport reports into. All optional ones are genuinely optional — a headless consumer can skip them. */
65
+ export interface SandboxBrowserTransportHandlers {
66
+ /** The media stream reached `ontrack`. */
67
+ onStream: (stream: MediaStream) => void;
68
+ /** Control changed hands. Fires with the server's view, including the initial one from `system/init`. */
69
+ onHostChange: (host: BrowserHost) => void;
70
+ /** Connection status moved; `detail` carries a human-readable reason for `error`. */
71
+ onStatus: (status: BrowserStatus, detail?: string) => void;
72
+ /**
73
+ * Position of the remote **X11** pointer, over the data channel — the video stream deliberately omits
74
+ * the cursor so position updates can outpace video encoding.
75
+ *
76
+ * Two consequences worth stating, because both look like bugs otherwise. The server does not send this
77
+ * to whoever holds control (that person has a zero-latency local cursor already). And the agent does not
78
+ * move the X11 pointer at all: it drives Chromium over CDP, whose input events are injected into the
79
+ * renderer and never reach X11. So while the agent works, this never fires — what the user sees change
80
+ * is the page content itself. This exists so that *another person* holding control has a visible pointer.
81
+ */
82
+ onRemoteCursor?: (position: RemoteCursorPosition | null) => void;
83
+ /**
84
+ * The remote clipboard changed. **Only the control holder receives this** — the server looks up the host
85
+ * first and skips everyone else. A viewer seeing nothing here is the design, not a fault.
86
+ */
87
+ onClipboardChange?: (text: string) => void;
88
+ /**
89
+ * Every WebSocket frame, both directions — for diagnostics harnesses (the neko lab page). `control/move`
90
+ * is excluded by the transport because its volume drowns out everything else.
91
+ */
92
+ onWire?: (direction: 'send' | 'recv', event: string, payload?: unknown) => void;
93
+ }
94
+ /** An established connection. Unusable once `close()` has been called. */
95
+ export interface SandboxBrowserSession {
96
+ /** Ask to take over. The server answers with `control/host` — or, if it refuses, with nothing at all. */
97
+ requestControl: () => void;
98
+ /** Give control back. */
99
+ releaseControl: () => void;
100
+ sendPointer: (event: RemotePointerEvent) => void;
101
+ sendKey: (event: RemoteKeyEvent) => void;
102
+ /**
103
+ * Write the local clipboard into the **remote** clipboard without pasting anything. Needed so the remote
104
+ * page's own paste affordances (its right-click menu, its JavaScript) have something to read — not just
105
+ * the one chord we can intercept. Requires control; the server rejects it silently otherwise.
106
+ */
107
+ setClipboard: (text: string) => void;
108
+ /**
109
+ * Have the remote perform a paste: the server sets the clipboard and synthesizes Ctrl+V **itself**.
110
+ *
111
+ * Going through the server rather than forwarding the user's ⌘V sidesteps two separate problems at once —
112
+ * the macOS Meta↔Control remap, and the browser swallowing a chorded character before `input` fires. It
113
+ * is also the only route that works in an iOS / Android WebView, where physical key interception is not
114
+ * reliable.
115
+ */
116
+ paste: (text: string) => void;
117
+ /** Tear down: heartbeat timer, peer connection, socket. */
118
+ close: () => void;
119
+ }
120
+ /**
121
+ * The seam between "draw the picture" and "carry the protocol".
122
+ *
123
+ * The panel holds one of these and knows nothing below it. The production implementation fetches session
124
+ * credentials and negotiates WebRTC; a demo implementation can hand back a canvas `captureStream()`; the
125
+ * neko lab swaps in a direct-login variant. Same component above all three, which is the check that this
126
+ * line was drawn in the right place.
127
+ */
128
+ export interface SandboxBrowserTransport {
129
+ connect: (sandboxName: string, handlers: SandboxBrowserTransportHandlers) => Promise<SandboxBrowserSession>;
130
+ }
131
+ //# sourceMappingURL=sandbox-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-browser.d.ts","sourceRoot":"","sources":["../../src/types/sandbox-browser.ts"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH,MAAM,WAAW,gCAAgC;IAC/C,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,mHAAmH;AACnH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE,yFAAyF;AACzF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;IAC7B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,iGAAiG;AACjG,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,wHAAwH;AACxH,MAAM,WAAW,+BAA+B;IAC9C,0CAA0C;IAC1C,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,yGAAyG;IACzG,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC1C,qFAAqF;IACrF,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACjF;AAED,0EAA0E;AAC1E,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,yBAAyB;IACzB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACjD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;;;;;OAOG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,2DAA2D;IAC3D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,+BAA+B,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC7G"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asgard-js/core",
3
- "version": "0.3.84",
3
+ "version": "0.3.86",
4
4
  "dependencies": {
5
5
  "@microsoft/fetch-event-source": "^2.0.1",
6
6
  "rxjs": "^7.8.1",