overmux 0.0.10 → 0.0.12
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/CHANGELOG.md +22 -0
- package/dist/bin.js +145 -58
- package/dist/bin.js.map +1 -1
- package/dist/docs/400-reference/200-configuration.md +54 -4
- package/dist/docs/400-reference/500-server/000-index.md +4 -0
- package/dist/docs/400-reference/500-server/100-resources.md +5 -0
- package/dist/docs/400-reference/500-server/200-operations.md +1 -0
- package/dist/docs/400-reference/500-server/300-streams.md +7 -1
- package/dist/docs/400-reference/500-server/400-notifications.md +4 -0
- package/dist/docs/400-reference/500-server/500-api.md +26 -5
- package/dist/exports/client.d.ts +1 -1
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +55 -14
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/{index-Dk11nKIv.d.ts → index-C-8Kzrnc.d.ts} +23 -8
- package/dist/exports/index-C-8Kzrnc.d.ts.map +1 -0
- package/dist/exports/index.d.ts +2 -2
- package/dist/exports/index.js +1 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/{notifications-BFAD3QQl.js → notifications-BBKvKZgI.js} +8 -2
- package/dist/exports/{notifications-BFAD3QQl.js.map → notifications-BBKvKZgI.js.map} +1 -1
- package/dist/exports/server.d.ts.map +1 -1
- package/dist/exports/server.js +8 -2
- package/dist/exports/server.js.map +1 -1
- package/dist/internal/server/coordinator/server-child.js +616 -883
- package/dist/internal/server/coordinator/server-child.js.map +1 -1
- package/dist/internal/server/worker-entry.d.ts +1 -0
- package/dist/internal/server/worker-entry.js +728 -0
- package/dist/internal/server/worker-entry.js.map +1 -0
- package/dist/push/THIRD_PARTY_NOTICES.md +30 -0
- package/dist/push/badge.png +0 -0
- package/dist/push/icon.png +0 -0
- package/dist/push/sw.js +88 -0
- package/dist/push/sw.js.map +1 -0
- package/dist/worker-protocol-hXs4FXCH.js +638 -0
- package/dist/worker-protocol-hXs4FXCH.js.map +1 -0
- package/docs/400-reference/200-configuration.md +54 -4
- package/docs/400-reference/500-server/000-index.md +4 -0
- package/docs/400-reference/500-server/100-resources.md +5 -0
- package/docs/400-reference/500-server/200-operations.md +1 -0
- package/docs/400-reference/500-server/300-streams.md +7 -1
- package/docs/400-reference/500-server/400-notifications.md +4 -0
- package/docs/400-reference/500-server/500-api.md +26 -5
- package/package.json +4 -3
- package/src/internal/client/background-notifications.ts +3 -1
- package/src/internal/client/host/hosted-pages/browser-notification-settings.tsx +8 -3
- package/src/internal/client/host/overmux-host.tsx +4 -8
- package/src/internal/client/push-assets/badge.png +0 -0
- package/src/internal/client/push-assets/icon.png +0 -0
- package/src/internal/client/push-service-worker.ts +118 -0
- package/src/internal/client/register-push-worker.ts +63 -0
- package/src/internal/server/coordinator/ipc-protocol.ts +2 -1
- package/src/internal/server/http/operation-handler.ts +3 -0
- package/src/internal/server/http/request-logging.ts +1 -1
- package/src/internal/server/http/routes.ts +47 -2
- package/src/internal/server/protocol-error.ts +19 -0
- package/src/internal/server/runtime/create-runtime.ts +11 -5
- package/src/internal/server/runtime/handler-logger.ts +54 -0
- package/src/internal/server/runtime/runtime-operations.ts +23 -5
- package/src/internal/server/runtime/runtime-resources.ts +158 -88
- package/src/internal/server/runtime/runtime-streams.ts +24 -8
- package/src/internal/server/runtime/worker-capabilities.ts +67 -0
- package/src/internal/server/runtime/worker-connection.ts +549 -0
- package/src/internal/server/runtime/worker-protocol.ts +173 -0
- package/src/internal/server/runtime/worker-runtime.ts +214 -0
- package/src/internal/server/server-logger.ts +25 -37
- package/src/internal/server/server-startup-options.ts +7 -6
- package/src/internal/server/start-application-server.ts +22 -18
- package/src/internal/server/start-overmux-server.ts +2 -2
- package/src/internal/server/websocket-connection.ts +97 -32
- package/src/internal/server/websocket-server.ts +5 -1
- package/src/internal/server/worker-entry.ts +504 -0
- package/src/internal/shared/protocol.ts +3 -3
- package/src/internal/shared/routes.ts +2 -0
- package/src/public/config.ts +15 -23
- package/src/public/handler-logger.ts +7 -0
- package/src/public/index.ts +3 -1
- package/dist/exports/index-Dk11nKIv.d.ts.map +0 -1
|
@@ -161,7 +161,7 @@ export default defineOvermuxConfig({
|
|
|
161
161
|
|
|
162
162
|
See [`overmux serve`](/docs/reference/cli/serve) for development mode.
|
|
163
163
|
|
|
164
|
-
### `
|
|
164
|
+
### `logLevel`
|
|
165
165
|
|
|
166
166
|
```ts
|
|
167
167
|
import { defineOvermuxConfig } from "overmux";
|
|
@@ -169,12 +169,27 @@ import { defineOvermuxConfig } from "overmux";
|
|
|
169
169
|
export default defineOvermuxConfig({
|
|
170
170
|
// ...other config
|
|
171
171
|
|
|
172
|
-
// Default:
|
|
173
|
-
//
|
|
174
|
-
|
|
172
|
+
// Default: "info", in development and production.
|
|
173
|
+
// Options: "debug", "info", "warn", "error".
|
|
174
|
+
logLevel: "info",
|
|
175
175
|
});
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
+
`logLevel` sets the minimum severity for runtime and [structured handler logs](./500-server/500-api.md#logging):
|
|
179
|
+
|
|
180
|
+
| Level | Written events |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| `"debug"` | debug, info, warn, error |
|
|
183
|
+
| `"info"` (default) | info, warn, error |
|
|
184
|
+
| `"warn"` | warn, error |
|
|
185
|
+
| `"error"` | error |
|
|
186
|
+
|
|
187
|
+
Server startup/shutdown are info events; routine HTTP requests, WebSocket connections, and operation start/completion are debug events. Lifecycle events do not bypass the threshold. Logs go to the server JSONL file and stderr; existing stdout/stderr journal capture is unchanged.
|
|
188
|
+
|
|
189
|
+
Browser console forwarding is enabled only at `"debug"`, not at the other levels, even for browser console errors. Treat this as diagnostic capture that may contain application data.
|
|
190
|
+
|
|
191
|
+
This replaces the removed `debug` boolean. Use `logLevel: "debug"` for investigation, or omit the option for normal `"info"` logging. Configuration using `debug` is rejected.
|
|
192
|
+
|
|
178
193
|
See [Storage locations](/docs/reference/storage-locations) for the server log location.
|
|
179
194
|
|
|
180
195
|
### `aiContextSnippets`
|
|
@@ -255,3 +270,38 @@ export default defineOvermuxDesktopConfig({
|
|
|
255
270
|
macosTrafficLights: "hidden",
|
|
256
271
|
});
|
|
257
272
|
```
|
|
273
|
+
|
|
274
|
+
### `onBeforeInputEvent`
|
|
275
|
+
|
|
276
|
+
The optional `onBeforeInputEvent` callback exposes Electron's [`before-input-event`](https://www.electronjs.org/docs/latest/api/web-contents#event-before-input-event), receiving the actual Electron `Event`, `Input`, and receiving [`WebContents`](https://www.electronjs.org/docs/latest/api/web-contents).
|
|
277
|
+
|
|
278
|
+
You can use this callback to intercept Electron key presses.
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
import { defineOvermuxDesktopConfig } from "@overmux/desktop";
|
|
283
|
+
|
|
284
|
+
export default defineOvermuxDesktopConfig({
|
|
285
|
+
onBeforeInputEvent: ({ event, input, webContents }) => {
|
|
286
|
+
const key = input.key.toLowerCase();
|
|
287
|
+
if (
|
|
288
|
+
process.platform !== "linux" ||
|
|
289
|
+
input.type !== "keyDown" ||
|
|
290
|
+
!input.meta ||
|
|
291
|
+
input.control ||
|
|
292
|
+
input.alt ||
|
|
293
|
+
input.shift ||
|
|
294
|
+
(key !== "c" && key !== "v")
|
|
295
|
+
) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
event.preventDefault();
|
|
300
|
+
if (key === "c") {
|
|
301
|
+
webContents.copy();
|
|
302
|
+
} else {
|
|
303
|
+
webContents.paste();
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
```
|
|
@@ -11,3 +11,7 @@ Overmux's server architecture provides three primitives that package authors can
|
|
|
11
11
|
- [Streams](./300-streams.md): Provide low-latency, bidirectional data flow between your UI and server, such as terminal input/output or live AI agent output.
|
|
12
12
|
|
|
13
13
|
See [Notifications](./400-notifications.md) for sending notifications and [Server API](./500-api.md) for definition helpers and handler context.
|
|
14
|
+
|
|
15
|
+
## Execution model
|
|
16
|
+
|
|
17
|
+
Overmux uses workers, which are separate JavaScript threads. Resources and operations share one worker, while each named stream has its own. This keeps resource and operation work from blocking streams, helping streams stay responsive.
|
|
@@ -96,6 +96,8 @@ subscribe: async (_input, invalidate, context) => {
|
|
|
96
96
|
|
|
97
97
|
`context.signal` is an `AbortSignal` that Overmux aborts when the client unsubscribes, disconnects, or the server shuts down. Cancellation does not automatically stop an async function: pass the signal to APIs that support it and check it after awaiting setup. Here, `realpath` does not accept a signal, so `throwIfAborted()` prevents starting a watcher if cancellation happened during that work.
|
|
98
98
|
|
|
99
|
+
Both `read` and `subscribe` receive `context.logger` for [structured logging](./500-api.md#logging), including during cleanup.
|
|
100
|
+
|
|
99
101
|
Overmux calls the returned cleanup function once, even if setup finishes after cancellation. Cleanup may also be asynchronous. In this example, the signal can close the watcher before Overmux calls cleanup; `watcher.close()` is safe to call again. If setup throws before returning cleanup, your handler must release any resources it already acquired.
|
|
100
102
|
|
|
101
103
|
## Derived
|
|
@@ -105,6 +107,9 @@ Derived resources compute a value from other resources.
|
|
|
105
107
|
For example, count the entries returned by the `ls` resource above. Add `entryCount` alongside `ls` in your `resources` object:
|
|
106
108
|
|
|
107
109
|
```ts
|
|
110
|
+
import { defineOvermuxServer, defineResourceContract, noInputSchema } from "overmux";
|
|
111
|
+
import { z } from "zod";
|
|
112
|
+
|
|
108
113
|
defineOvermuxServer({
|
|
109
114
|
resources: {
|
|
110
115
|
ls: {
|
|
@@ -43,6 +43,7 @@ handle: async (input, context) => {
|
|
|
43
43
|
|
|
44
44
|
- **`invalidate(resourceId, input?)`**: tells clients to read an affected resource again after you change server-side data. See [Invalidating resources](./100-resources.md#invalidating-resources).
|
|
45
45
|
- **[`notifications.send(...)`](./400-notifications.md)**: sends a notification through Overmux.
|
|
46
|
+
- **[`logger`](./500-api.md#logging)**: writes structured logs with `debug`, `info`, `warn`, and `error`.
|
|
46
47
|
|
|
47
48
|
See [Server API](./500-api.md#handler-context) for the full handler context.
|
|
48
49
|
|
|
@@ -129,12 +129,18 @@ Overmux calls `dispose` once when the session closes. Use it to stop timers, rem
|
|
|
129
129
|
|
|
130
130
|
`useStream` closes its session when the component unmounts. You can also close it explicitly with `close()`.
|
|
131
131
|
|
|
132
|
-
The
|
|
132
|
+
The stream context provides an abort `signal` for cancelling background work and `fail(cause)` for failing and closing the session. See [Server API: Stream handlers](./500-api.md#stream-handlers).
|
|
133
|
+
|
|
134
|
+
Use `context.logger` for [structured logging](./500-api.md#logging) in the handler and its message and cleanup callbacks.
|
|
133
135
|
|
|
134
136
|
## How streams work
|
|
135
137
|
|
|
136
138
|
Streams communicate over a persistent WebSocket connection between your browser and server.
|
|
137
139
|
|
|
140
|
+
Each named stream runs in its own worker. Resources, including derived resources, and operations share a separate application worker; module-local state is not shared with streams. See [Configuration](../200-configuration.md#server).
|
|
141
|
+
|
|
142
|
+
Streams cannot invalidate resources. To mutate data and invalidate affected resources, have the client call an [operation](./200-operations.md). To refresh resources when an external source changes, use a [subscription resource watcher](./100-resources.md#subscription). A stream does not automatically invoke an operation.
|
|
143
|
+
|
|
138
144
|
Overmux validates the opening input and messages against the stream contract. Client messages are passed to `onMessage` in order; calls to `emit` send messages to that session's client.
|
|
139
145
|
|
|
140
146
|
A restored stream after a WebSocket reconnect creates a new server session. Do not assume that state held by the previous session survives.
|
|
@@ -30,3 +30,7 @@ export const serverConfig = defineOvermuxServer({
|
|
|
30
30
|
- `open.link`: optional destination to open when the notification is activated. Use an app-relative path starting with `/` or an HTTP(S) URL without credentials.
|
|
31
31
|
|
|
32
32
|
Each text field and link has a maximum length of 4,096 characters. `send()` returns `Promise<void>`.
|
|
33
|
+
|
|
34
|
+
## PWA background notifications
|
|
35
|
+
|
|
36
|
+
Open `/_overmux/settings` on your Overmux server, and enable browser notifications. This requires HTTPS, or localhost for development. See [Hosted pages](../../500-hosted-pages.md) for adding a settings link to your application.
|
|
@@ -40,6 +40,8 @@ export const serverConfig = defineOvermuxServer({
|
|
|
40
40
|
|
|
41
41
|
Object keys are the IDs used by clients. See [Resources](./100-resources.md), [Operations](./200-operations.md), and [Streams](./300-streams.md) for usage guides.
|
|
42
42
|
|
|
43
|
+
See [Configuration](../200-configuration.md#server) for worker ownership and shared-state constraints.
|
|
44
|
+
|
|
43
45
|
## Resource handlers
|
|
44
46
|
|
|
45
47
|
A resource definition has a `contract` created with `defineResourceContract({ input, output })`. Overmux parses handler input with `input` and validates every result with `output`.
|
|
@@ -71,7 +73,7 @@ const resources = {
|
|
|
71
73
|
|
|
72
74
|
`subscribe` returns a cleanup function, directly or asynchronously. Overmux aborts `context.signal` when the subscription ends, including during setup, on client disconnect, or on server shutdown. Overmux calls the returned cleanup function once, even if setup returns it after cancellation. The cleanup function itself may also be asynchronous. If setup throws before returning cleanup, the handler must release any resources it already acquired. See [Asynchronous setup](./100-resources.md#asynchronous-setup) for an example.
|
|
73
75
|
|
|
74
|
-
A derived resource reads the resources named by `dependencies`; invalidating a dependency also invalidates its dependants. See [Resources](./100-resources.md) for contracts, derived dependencies, and invalidation.
|
|
76
|
+
A derived resource reads the resources named by `dependencies`; invalidating a dependency also invalidates its dependants. See [Resources](./100-resources.md#derived) for contracts, derived dependencies, and invalidation.
|
|
75
77
|
|
|
76
78
|
## Stream handlers
|
|
77
79
|
|
|
@@ -88,10 +90,14 @@ const terminal = defineStreamHandler(contract, (input, context) => ({
|
|
|
88
90
|
}));
|
|
89
91
|
```
|
|
90
92
|
|
|
91
|
-
`open(input, context)` may return the session object or a promise for it.
|
|
93
|
+
`open(input, context)` may return the session object or a promise for it. Streams receive their own context, without `invalidate`:
|
|
92
94
|
|
|
93
95
|
| API | Purpose |
|
|
94
96
|
| --- | --- |
|
|
97
|
+
| `signal` | An `AbortSignal` that aborts when the session or server runtime closes. |
|
|
98
|
+
| `instance.getInstanceId()` | Get this server instance's ID. |
|
|
99
|
+
| `instance.getDeepLinkPrefix()` | Get this instance's Overmux deep-link prefix. |
|
|
100
|
+
| `logger` | Write [structured handler logs](#logging), including from `onMessage` and `dispose` closures. |
|
|
95
101
|
| `emit(message)` | Validate and send a server message to this session. Calls after closure are ignored. |
|
|
96
102
|
| `fail(cause)` | Fail and close this session. A later call has no effect. |
|
|
97
103
|
|
|
@@ -106,15 +112,30 @@ The stream `signal` aborts when its session or the runtime closes. Stop backgrou
|
|
|
106
112
|
|
|
107
113
|
## Handler context
|
|
108
114
|
|
|
109
|
-
Inline resource
|
|
115
|
+
Inline resource and operation handlers infer valid resource IDs and inputs.
|
|
110
116
|
|
|
111
|
-
Resource
|
|
117
|
+
Resource handlers receive a context with:
|
|
112
118
|
|
|
113
119
|
| API | Purpose |
|
|
114
120
|
| --- | --- |
|
|
115
121
|
| `invalidate(resourceId, input?)` | Ask clients to [read a resource again](./100-resources.md#invalidating-resources). Pass the resource's key in `resources`. Omit `input` to invalidate all inputs; otherwise it is validated and only matching inputs are invalidated. Unknown IDs throw. |
|
|
116
|
-
| `
|
|
122
|
+
| `logger` | Write [structured handler logs](#logging). |
|
|
123
|
+
| `signal` | An `AbortSignal` that aborts when the request or subscription, or the server runtime, closes. |
|
|
117
124
|
| `instance.getInstanceId()` | Get this server instance's ID. |
|
|
118
125
|
| `instance.getDeepLinkPrefix()` | Get this instance's Overmux deep-link prefix. |
|
|
119
126
|
|
|
120
127
|
Operation handlers receive the same context plus `notifications.send(notification)`, which returns `Promise<void>`. See [Notifications](./400-notifications.md).
|
|
128
|
+
|
|
129
|
+
### Logging
|
|
130
|
+
|
|
131
|
+
Resource, stream, and operation handlers receive `context.logger`, with synchronous `debug`, `info`, `warn`, and `error` methods:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
logger.info("read-complete", { count: 42 });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Each method accepts an event name and optional `Record<string, unknown>` details, returning `void`. The public type is `HandlerLogger` from `overmux`.
|
|
138
|
+
|
|
139
|
+
Overmux automatically adds capability and request/session identity, including in message and cleanup closures. Logs go to the [server log file](/docs/reference/storage-locations) and stderr, filtered by [`logLevel`](../200-configuration.md#loglevel), which defaults to `"info"`.
|
|
140
|
+
|
|
141
|
+
Logging remains usable after cancellation, and logging failures never fail handlers or cleanup. Delivery is best effort: oversized entries and logs that exceed a worker's bounded queue are dropped rather than delaying application work. Inputs, results, and stream contents are not logged automatically. Avoid secrets or sensitive payloads in your events and details.
|
package/dist/exports/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as InstanceIdentity, T as ContractInputArguments } from "./index-C-8Kzrnc.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { UseMutationResult } from "@tanstack/react-query";
|
|
4
4
|
import { CSSProperties, ComponentType, ReactNode, RefObject } from "react";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/internal/client/background-notifications.ts","../../src/internal/client/native-web-view.tsx","../../src/internal/client/host/desktop-host.ts","../../src/internal/client/clipboard.ts","../../src/internal/client/browser-api.ts","../../src/internal/client/theme-scope.tsx","../../src/internal/client/client-definition.ts","../../src/internal/client/commands.tsx","../../src/internal/client/overmux-react.ts","../../src/internal/client/host/overmux-host.tsx","../../src/internal/client/shortcuts.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../../src/internal/client/background-notifications.ts","../../src/internal/client/native-web-view.tsx","../../src/internal/client/host/desktop-host.ts","../../src/internal/client/clipboard.ts","../../src/internal/client/browser-api.ts","../../src/internal/client/theme-scope.tsx","../../src/internal/client/client-definition.ts","../../src/internal/client/commands.tsx","../../src/internal/client/overmux-react.ts","../../src/internal/client/host/overmux-host.tsx","../../src/internal/client/shortcuts.tsx"],"mappings":"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"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./style.css";
|
|
2
|
-
import {
|
|
2
|
+
import { i as logLevelSchema, l as parseDeepLink, o as notificationSchema, r as instanceIdSchema, s as overmuxLogoutPath, t as createInstanceIdentity, u as resolveOvermuxReturnTo } from "./notifications-BBKvKZgI.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { QueryClient, QueryClientProvider, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
5
|
import { Component, createContext, createElement, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -26,9 +26,9 @@ const webSocketCloseCode = {
|
|
|
26
26
|
authenticationUnavailable: 4002
|
|
27
27
|
};
|
|
28
28
|
const runtimeManifestSchema = z.object({
|
|
29
|
-
|
|
29
|
+
logLevel: logLevelSchema,
|
|
30
30
|
operations: z.array(z.string().min(1)),
|
|
31
|
-
protocolVersion: z.literal(
|
|
31
|
+
protocolVersion: z.literal(11),
|
|
32
32
|
resources: z.array(z.string().min(1)),
|
|
33
33
|
streams: z.array(z.string().min(1))
|
|
34
34
|
});
|
|
@@ -192,6 +192,42 @@ const decodeProtocolFrame = (frame) => {
|
|
|
192
192
|
return decodeBinaryValue(header, bytes.subarray(8 + headerLength));
|
|
193
193
|
};
|
|
194
194
|
//#endregion
|
|
195
|
+
//#region src/internal/client/register-push-worker.ts
|
|
196
|
+
const registerPushWorker = () => new Promise((resolve, reject) => {
|
|
197
|
+
let watched = null;
|
|
198
|
+
let settled = false;
|
|
199
|
+
const finish = (error, registration) => {
|
|
200
|
+
if (settled) return;
|
|
201
|
+
settled = true;
|
|
202
|
+
clearTimeout(timeout);
|
|
203
|
+
watched?.removeEventListener("statechange", onStateChange);
|
|
204
|
+
if (error) reject(error);
|
|
205
|
+
else resolve(registration);
|
|
206
|
+
};
|
|
207
|
+
let registered;
|
|
208
|
+
const onStateChange = () => {
|
|
209
|
+
if (watched?.state === "activated") finish(void 0, registered);
|
|
210
|
+
else if (watched?.state === "redundant") finish(/* @__PURE__ */ new Error("The background notification worker failed to activate"));
|
|
211
|
+
};
|
|
212
|
+
const timeout = setTimeout(() => {
|
|
213
|
+
finish(/* @__PURE__ */ new Error("Timed out starting the background notification worker"));
|
|
214
|
+
}, 1e4);
|
|
215
|
+
navigator.serviceWorker.register("/sw.js", {
|
|
216
|
+
scope: "/",
|
|
217
|
+
updateViaCache: "none"
|
|
218
|
+
}).then((registration) => {
|
|
219
|
+
if (settled) return;
|
|
220
|
+
registered = registration;
|
|
221
|
+
watched = registration.active ?? registration.installing ?? registration.waiting;
|
|
222
|
+
if (!watched) {
|
|
223
|
+
finish(/* @__PURE__ */ new Error("No background notification worker was installed"));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
watched.addEventListener("statechange", onStateChange);
|
|
227
|
+
onStateChange();
|
|
228
|
+
}, (error) => finish(error instanceof Error ? error : new Error(String(error))));
|
|
229
|
+
});
|
|
230
|
+
//#endregion
|
|
195
231
|
//#region src/internal/client/background-notifications.ts
|
|
196
232
|
const enabledStorageKey = "overmux.backgroundNotificationsEnabled";
|
|
197
233
|
const isIos = () => /iPad|iPhone|iPod/u.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
@@ -257,7 +293,7 @@ const removeCurrentSubscription = async () => {
|
|
|
257
293
|
if (!await subscription.unsubscribe()) throw new Error("The background subscription could not be removed");
|
|
258
294
|
};
|
|
259
295
|
const reconcileBackgroundNotifications = async () => {
|
|
260
|
-
const registration = await
|
|
296
|
+
const registration = await registerPushWorker();
|
|
261
297
|
const publicKey = await getPublicKey();
|
|
262
298
|
let subscription = await registration.pushManager.getSubscription();
|
|
263
299
|
const subscriptionKey = subscription ? encodeApplicationServerKey(subscription.options.applicationServerKey) : void 0;
|
|
@@ -1510,13 +1546,17 @@ const statusMessage = (status) => {
|
|
|
1510
1546
|
};
|
|
1511
1547
|
const BrowserNotificationSettings = () => {
|
|
1512
1548
|
const [status, setStatus] = useState("checking");
|
|
1549
|
+
const [error, setError] = useState();
|
|
1513
1550
|
useEffect(() => {
|
|
1514
1551
|
let active = true;
|
|
1515
1552
|
const reconcile = () => {
|
|
1516
1553
|
reconciledStatus().then((next) => {
|
|
1517
1554
|
if (active) setStatus(next);
|
|
1518
|
-
}).catch(() => {
|
|
1519
|
-
if (active)
|
|
1555
|
+
}).catch((cause) => {
|
|
1556
|
+
if (active) {
|
|
1557
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1558
|
+
setStatus("error");
|
|
1559
|
+
}
|
|
1520
1560
|
});
|
|
1521
1561
|
};
|
|
1522
1562
|
const onVisibilityChange = () => {
|
|
@@ -1536,7 +1576,8 @@ const BrowserNotificationSettings = () => {
|
|
|
1536
1576
|
setStatus("checking");
|
|
1537
1577
|
const enabled = await enableBackgroundNotifications();
|
|
1538
1578
|
setStatus(enabled ? "enabled" : Notification.permission === "denied" ? "denied" : "disabled");
|
|
1539
|
-
} catch {
|
|
1579
|
+
} catch (cause) {
|
|
1580
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1540
1581
|
setStatus("error");
|
|
1541
1582
|
}
|
|
1542
1583
|
}, []);
|
|
@@ -1545,7 +1586,8 @@ const BrowserNotificationSettings = () => {
|
|
|
1545
1586
|
setStatus("checking");
|
|
1546
1587
|
await disableBackgroundNotifications();
|
|
1547
1588
|
setStatus("disabled");
|
|
1548
|
-
} catch {
|
|
1589
|
+
} catch (cause) {
|
|
1590
|
+
setError(cause instanceof Error ? cause.message : void 0);
|
|
1549
1591
|
setStatus("error");
|
|
1550
1592
|
}
|
|
1551
1593
|
}, []);
|
|
@@ -1555,10 +1597,10 @@ const BrowserNotificationSettings = () => {
|
|
|
1555
1597
|
"data-om-browser-notifications": "",
|
|
1556
1598
|
children: [
|
|
1557
1599
|
/* @__PURE__ */ jsx("h3", { children: "Browser notifications" }),
|
|
1558
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsxs("p", {
|
|
1559
1601
|
"aria-live": "polite",
|
|
1560
1602
|
"data-om-background-notifications-status": "",
|
|
1561
|
-
children: statusMessage(status)
|
|
1603
|
+
children: [statusMessage(status), status === "error" && error ? ` ${error}` : null]
|
|
1562
1604
|
}),
|
|
1563
1605
|
/* @__PURE__ */ jsxs("div", {
|
|
1564
1606
|
"data-om-hosted-actions": "",
|
|
@@ -1820,7 +1862,6 @@ const OvermuxRuntime = ({ definition }) => {
|
|
|
1820
1862
|
const safeMode = new URLSearchParams(location.search).get("safe") === "1";
|
|
1821
1863
|
const transport = useMemo(createClientTransport, []);
|
|
1822
1864
|
const queryClient = useMemo(() => new QueryClient(), []);
|
|
1823
|
-
const logForwardingDisposer = useRef(void 0);
|
|
1824
1865
|
const [manifest, setManifest] = useState();
|
|
1825
1866
|
const [error, setError] = useState();
|
|
1826
1867
|
useEffect(() => {
|
|
@@ -1843,13 +1884,13 @@ const OvermuxRuntime = ({ definition }) => {
|
|
|
1843
1884
|
const registrations = useMemo(() => /* @__PURE__ */ new Set(), []);
|
|
1844
1885
|
const [registrationRevision, setRegistrationRevision] = useState(0);
|
|
1845
1886
|
useEffect(() => {
|
|
1846
|
-
if (manifest?.
|
|
1847
|
-
|
|
1887
|
+
if (manifest?.logLevel !== "debug") return;
|
|
1888
|
+
return installBrowserLogForwarding(transport.reportDiagnostic);
|
|
1889
|
+
}, [manifest?.logLevel, transport]);
|
|
1848
1890
|
useEffect(() => transport.subscribeStatus((status) => {
|
|
1849
1891
|
if (status === "authentication-required") redirectToLogin();
|
|
1850
1892
|
}), [transport]);
|
|
1851
1893
|
useEffect(() => () => {
|
|
1852
|
-
logForwardingDisposer.current?.();
|
|
1853
1894
|
transport.dispose();
|
|
1854
1895
|
}, [transport]);
|
|
1855
1896
|
useEffect(() => installNotificationForwarding(transport), [transport]);
|