@nervur-org/dock 0.3.1 → 0.4.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/GETTING_STARTED.md +22 -12
- package/{beings/GLOSSARY.md → GLOSSARY.md} +3 -3
- package/NOTICE +1 -1
- package/README.md +20 -16
- package/{beings/WORLDS.md → WORLDS.md} +6 -4
- package/api/route.ts +3 -3
- package/beings/avatar.ts +2 -2
- package/beings/carry.ts +2 -2
- package/beings/clock.ts +2 -2
- package/beings/courier.ts +2 -2
- package/beings/desk.ts +2 -2
- package/beings/doorbell.ts +2 -2
- package/beings/envoy.ts +2 -2
- package/beings/join.ts +2 -2
- package/beings/link.ts +5 -5
- package/beings/look.ts +1 -1
- package/beings/porter.ts +2 -2
- package/beings/presence.ts +1 -1
- package/beings/setup.ts +3 -3
- package/beings/side.ts +2 -2
- package/beings/user.ts +2 -2
- package/beings/way.ts +1 -1
- package/cli/client.ts +6 -6
- package/cli/daemon.ts +7 -7
- package/cli/estate/{quo.service → nervur.service} +12 -12
- package/cli/estate/org.nervur.plist +44 -0
- package/cli/estate.ts +6 -6
- package/cli/{quo.ts → nervur.ts} +43 -37
- package/cli/pilot.ts +3 -3
- package/cli/stand.ts +3 -3
- package/dist/api/route.d.ts +2 -2
- package/dist/api/route.js +2 -2
- package/dist/beings/avatar.d.ts +1 -1
- package/dist/beings/avatar.js +1 -1
- package/dist/beings/carry.d.ts +2 -2
- package/dist/beings/carry.js +1 -1
- package/dist/beings/clock.d.ts +2 -2
- package/dist/beings/clock.js +1 -1
- package/dist/beings/courier.d.ts +2 -2
- package/dist/beings/courier.js +1 -1
- package/dist/beings/desk.d.ts +3 -3
- package/dist/beings/desk.js +1 -1
- package/dist/beings/doorbell.d.ts +3 -3
- package/dist/beings/doorbell.js +1 -1
- package/dist/beings/envoy.d.ts +2 -2
- package/dist/beings/envoy.js +1 -1
- package/dist/beings/join.d.ts +2 -2
- package/dist/beings/link.d.ts +2 -2
- package/dist/beings/link.js +3 -3
- package/dist/beings/look.d.ts +1 -1
- package/dist/beings/porter.d.ts +2 -2
- package/dist/beings/porter.js +1 -1
- package/dist/beings/presence.d.ts +1 -1
- package/dist/beings/setup.d.ts +1 -1
- package/dist/beings/side.d.ts +1 -1
- package/dist/beings/side.js +1 -1
- package/dist/beings/user.d.ts +3 -3
- package/dist/beings/user.js +1 -1
- package/dist/beings/way.d.ts +1 -1
- package/dist/cli/client.js +4 -4
- package/dist/cli/daemon.d.ts +1 -1
- package/dist/cli/daemon.js +6 -6
- package/dist/cli/estate/{quo.service → nervur.service} +12 -12
- package/dist/cli/estate/org.nervur.plist +44 -0
- package/dist/cli/estate.js +6 -6
- package/dist/cli/{quo.js → nervur.js} +43 -37
- package/dist/cli/stand.d.ts +2 -2
- package/dist/dock/agents.d.ts +1 -1
- package/dist/dock/agents.js +1 -1
- package/dist/dock/apns.js +1 -1
- package/dist/dock/console.d.ts +1 -1
- package/dist/dock/dialers.d.ts +2 -2
- package/dist/dock/dialers.js +2 -2
- package/dist/dock/faculty.d.ts +2 -2
- package/dist/dock/faculty.js +1 -1
- package/dist/dock/grants.d.ts +1 -1
- package/dist/dock/grants.js +1 -1
- package/dist/dock/http2.js +1 -1
- package/dist/dock/index.d.ts +1 -1
- package/dist/dock/index.js +1 -1
- package/dist/dock/local.d.ts +2 -2
- package/dist/dock/location.d.ts +1 -1
- package/dist/dock/notifications.d.ts +1 -1
- package/dist/dock/notifications.js +1 -1
- package/dist/dock/push.d.ts +1 -1
- package/dist/dock/push.js +3 -3
- package/dist/dock/service.js +1 -1
- package/dist/dock/timer.d.ts +1 -1
- package/dist/harbor/browser.d.ts +2 -2
- package/dist/harbor/browser.js +4 -4
- package/dist/harbor/capacitor.d.ts +1 -1
- package/dist/harbor/capacitor.js +1 -1
- package/dist/harbor/disk.d.ts +4 -4
- package/dist/harbor/disk.js +5 -5
- package/dist/harbor/edge/edge.d.ts +2 -2
- package/dist/harbor/edge/edge.js +5 -5
- package/dist/harbor/edge/exercise.js +8 -8
- package/dist/harbor/edge/given.d.ts +1 -1
- package/dist/harbor/edge/platform.d.ts +1 -1
- package/dist/harbor/edge/storage.d.ts +1 -1
- package/dist/harbor/edge/storage.js +2 -2
- package/dist/harbor/edge/worker.js +2 -2
- package/dist/harbor/files.d.ts +1 -1
- package/dist/harbor/files.js +2 -2
- package/dist/harbor/http.d.ts +2 -2
- package/dist/harbor/http.js +1 -1
- package/dist/harbor/idb.d.ts +1 -1
- package/dist/harbor/idb.js +0 -0
- package/dist/harbor/quo.js +1 -1
- package/dist/harbor/seal.js +1 -1
- package/dist/harbor/sealed.d.ts +1 -1
- package/dist/harbor/sealed.js +4 -4
- package/dist/harbor/tauri.d.ts +1 -1
- package/dist/harbor/tauri.js +1 -1
- package/dist/harbor/ward.d.ts +1 -1
- package/dist/human/app.d.ts +2 -2
- package/dist/human/door.js +4 -4
- package/dist/human/guest.js +1 -1
- package/dist/human/html.d.ts +1 -1
- package/dist/human/html.js +1 -1
- package/dist/human/local.d.ts +1 -1
- package/dist/human/mark.js +2 -2
- package/dist/human/move.d.ts +2 -2
- package/dist/human/move.js +1 -1
- package/dist/human/screen.d.ts +1 -1
- package/dist/human/screen.js +3 -3
- package/dist/human/tab.bundle.txt +32 -32
- package/dist/human/tab.js +7 -7
- package/dist/human/tree.d.ts +1 -1
- package/dist/human/wake.d.ts +2 -2
- package/dist/human/wake.js +1 -1
- package/dist/human/web.d.ts +1 -1
- package/dist/human/web.js +4 -4
- package/dist/human/worker.bundle.txt +27 -27
- package/dist/human/worker.js +4 -4
- package/dist/human/worlds.d.ts +2 -2
- package/dist/human/worlds.js +4 -4
- package/dist/mcp/agent.d.ts +1 -1
- package/dist/mcp/allow.d.ts +1 -1
- package/dist/mcp/allow.js +2 -2
- package/dist/mcp/oauth.js +1 -1
- package/dist/mcp/runner.d.ts +1 -1
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +2 -2
- package/dock/agents.ts +2 -2
- package/dock/apns.ts +1 -1
- package/dock/console.ts +1 -1
- package/dock/dialers.ts +3 -3
- package/dock/faculty.ts +2 -2
- package/dock/grants.ts +2 -2
- package/dock/http2.ts +1 -1
- package/dock/index.ts +3 -3
- package/dock/local.ts +1 -1
- package/dock/location.ts +1 -1
- package/dock/notifications.ts +2 -2
- package/dock/push.ts +4 -4
- package/dock/service.ts +1 -1
- package/dock/timer.ts +1 -1
- package/harbor/browser.ts +5 -5
- package/harbor/capacitor.ts +2 -2
- package/harbor/disk.ts +8 -8
- package/harbor/edge/edge.ts +7 -7
- package/harbor/edge/exercise.ts +11 -11
- package/harbor/edge/given.ts +1 -1
- package/harbor/edge/platform.d.ts +1 -1
- package/harbor/edge/storage.ts +2 -2
- package/harbor/edge/worker.ts +2 -2
- package/harbor/edge/wrangler.toml +3 -3
- package/harbor/files.ts +2 -2
- package/harbor/http.ts +2 -2
- package/harbor/idb.ts +0 -0
- package/harbor/quo.ts +1 -1
- package/harbor/resolve.ts +1 -1
- package/harbor/seal.ts +1 -1
- package/harbor/sealed.ts +5 -5
- package/harbor/tauri.ts +2 -2
- package/harbor/ward.ts +1 -1
- package/human/app.ts +2 -2
- package/human/apps.ts +1 -1
- package/human/door.ts +4 -4
- package/human/guest.ts +2 -2
- package/human/html.ts +2 -2
- package/human/local.ts +1 -1
- package/human/mark.ts +2 -2
- package/human/move.ts +3 -3
- package/human/screen.ts +5 -5
- package/human/tab.bundle.txt +32 -32
- package/human/tab.ts +10 -10
- package/human/tree.ts +1 -1
- package/human/wake.ts +3 -3
- package/human/web.ts +5 -5
- package/human/worker.bundle.txt +27 -27
- package/human/worker.ts +6 -6
- package/human/worlds.ts +5 -5
- package/mcp/agent.ts +1 -1
- package/mcp/allow.ts +5 -5
- package/mcp/oauth.ts +1 -1
- package/mcp/runner.ts +1 -1
- package/mcp/server.ts +3 -3
- package/package.json +15 -7
- package/{api/quo-api.md → quo-api.md} +1 -1
- package/{beings/quo-dock.md → quo-dock.md} +74 -71
- package/{harbor/quo-harbor.md → quo-harbor.md} +54 -30
- package/{human/quo-human.md → quo-human.md} +7 -7
- package/{mcp/quo-mcp.md → quo-mcp.md} +10 -10
- package/cli/estate/systems.quo.plist +0 -44
- package/cli/quo-dock.md +0 -1942
- package/dist/cli/estate/systems.quo.plist +0 -44
- package/dock/quo-app-bells.md +0 -280
- package/dock/quo-dock.md +0 -1942
- /package/dist/cli/{quo.d.ts → nervur.d.ts} +0 -0
- /package/{beings/quo-app-bells.md → quo-app-bells.md} +0 -0
package/dist/human/worlds.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Avatar, USER } from '../beings/avatar.js';
|
|
2
2
|
import { settled } from '../dock/faculty.js';
|
|
3
|
-
// The list as a browser keeps it, the tab's and the app's alike: one item
|
|
4
|
-
// under
|
|
5
|
-
//
|
|
6
|
-
export const KEY = '
|
|
3
|
+
// The list as a browser keeps it, the tab's and the app's alike: one item
|
|
4
|
+
// under one key. A device with no storage still works and forgets, which is
|
|
5
|
+
// why every read has a floor.
|
|
6
|
+
export const KEY = 'nervur-worlds';
|
|
7
7
|
export function inStorage(storage) {
|
|
8
8
|
return {
|
|
9
9
|
read: () => {
|
package/dist/mcp/agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Json, JsonObject } from '
|
|
1
|
+
import type { Json, JsonObject } from 'nervur';
|
|
2
2
|
import type { Avatar } from '../beings/avatar.ts';
|
|
3
3
|
import { type Serving } from '../beings/side.ts';
|
|
4
4
|
export type Run = (event: JsonObject) => Promise<Json>;
|
package/dist/mcp/allow.d.ts
CHANGED
package/dist/mcp/allow.js
CHANGED
|
@@ -61,9 +61,9 @@ export class Exchange {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
// The one stylesheet, and no colour of this page's own. The policy is the
|
|
64
|
-
// one every page
|
|
64
|
+
// one every page the dock writes itself is served under, `human/door.ts`, since
|
|
65
65
|
// this is one of them: it runs no script of its own and wants none.
|
|
66
|
-
const shell = (body) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>
|
|
66
|
+
const shell = (body) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>nervur</title>
|
|
67
67
|
<style>${CSS}</style>
|
|
68
68
|
</head><body><main class="door">${body}</main></body></html>`;
|
|
69
69
|
// The one page, and every sentence on it is something a human needs in
|
package/dist/mcp/oauth.js
CHANGED
|
@@ -66,7 +66,7 @@ export class OAuth {
|
|
|
66
66
|
grant_types_supported: ['authorization_code', 'refresh_token'],
|
|
67
67
|
code_challenge_methods_supported: ['S256'],
|
|
68
68
|
token_endpoint_auth_methods_supported: ['none'],
|
|
69
|
-
scopes_supported: ['
|
|
69
|
+
scopes_supported: ['nervur'],
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
protectedResource() {
|
package/dist/mcp/runner.d.ts
CHANGED
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
2
|
import { type Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
-
import type { Blueprint } from '
|
|
3
|
+
import type { Blueprint } from 'nervur';
|
|
4
4
|
import { type Serving, type Subject } from '../beings/side.ts';
|
|
5
5
|
import { type Look } from '../beings/look.ts';
|
|
6
|
-
export declare const NAME = "
|
|
6
|
+
export declare const NAME = "nervur";
|
|
7
7
|
export declare const VERSION = "0.0.0";
|
|
8
8
|
export type { Subject } from '../beings/side.ts';
|
|
9
9
|
export declare const DESCRIBE: Tool;
|
package/dist/mcp/server.js
CHANGED
|
@@ -12,8 +12,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
12
12
|
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
13
13
|
import { word, wordText, SILENCE_TEXT, UNREACHED_TEXT } from '../beings/side.js';
|
|
14
14
|
import { hintFor, presentation, sanitise } from '../beings/look.js';
|
|
15
|
-
import { isSilence, isWord, digest } from '
|
|
16
|
-
export const NAME = '
|
|
15
|
+
import { isSilence, isWord, digest } from 'nervur';
|
|
16
|
+
export const NAME = 'nervur';
|
|
17
17
|
export const VERSION = '0.0.0';
|
|
18
18
|
// The empty ask as a tool: her describe whole, asks and notes.
|
|
19
19
|
export const DESCRIBE = { name: 'describe', description: 'the empty ask: her describe, the asks and the notes', inputSchema: { type: 'object' } };
|
package/dock/agents.ts
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
// to persist: running an agent is admitting through a socket only a daemon
|
|
22
22
|
// has, and this file is not in the dock's index, since a tab has no process
|
|
23
23
|
// to spawn. A box with no runner keeps the table and runs nobody.
|
|
24
|
-
import { OWNER } from '
|
|
25
|
-
import type { Asker, JsonObject, OccupantRecord } from '
|
|
24
|
+
import { OWNER } from 'nervur';
|
|
25
|
+
import type { Asker, JsonObject, OccupantRecord } from 'nervur';
|
|
26
26
|
import { Faculty } from './faculty.ts';
|
|
27
27
|
|
|
28
28
|
// The name the dock ward holds her under.
|
package/dock/apns.ts
CHANGED
|
@@ -100,7 +100,7 @@ export function request(a: Apns, jwt: string, token: Token, sealed?: string): {
|
|
|
100
100
|
const said =
|
|
101
101
|
sealed === undefined
|
|
102
102
|
? { aps: { 'content-available': 1 } }
|
|
103
|
-
: { aps: { alert: { 'loc-key': '
|
|
103
|
+
: { aps: { alert: { 'loc-key': 'nervur.ring' }, 'mutable-content': 1, sound: 'default' }, sealed };
|
|
104
104
|
return {
|
|
105
105
|
path: `/3/device/${device(token)}`,
|
|
106
106
|
headers: {
|
package/dock/console.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// She carries for whoever the harbor's root let in, and for nobody else: the
|
|
13
13
|
// root is the box, and it invites the one avatar its own screen runs.
|
|
14
14
|
import { Carrier } from '../beings/carry.ts';
|
|
15
|
-
import type { Asker, OccupantRecord } from '
|
|
15
|
+
import type { Asker, OccupantRecord } from 'nervur';
|
|
16
16
|
|
|
17
17
|
export const CONSOLE = 'console';
|
|
18
18
|
|
package/dock/dialers.ts
CHANGED
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
// library's, written on the standard socket surface, so this faculty holds
|
|
15
15
|
// on every terrain that has a socket; the daemon hands her the harbor to
|
|
16
16
|
// dial for, as it hands the agents faculty how to run a row.
|
|
17
|
-
import { OWNER } from '
|
|
18
|
-
import type { Asker, JsonObject, OccupantRecord } from '
|
|
19
|
-
import { dial, type Dialer, type Harbor } from '
|
|
17
|
+
import { OWNER } from 'nervur';
|
|
18
|
+
import type { Asker, JsonObject, OccupantRecord } from 'nervur';
|
|
19
|
+
import { dial, type Dialer, type Harbor } from 'nervur/harbor';
|
|
20
20
|
import { Faculty } from './faculty.ts';
|
|
21
21
|
|
|
22
22
|
// The name the dock ward holds her under.
|
package/dock/faculty.ts
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
// connection, the interval, the worker, the route are opened in her
|
|
18
18
|
// constructor, and she is born whether or not the thing is reachable,
|
|
19
19
|
// answering an error object while it is not.
|
|
20
|
-
import { Being, isInvitation, isSilence, isWord, wordOf } from '
|
|
21
|
-
import type { Asker, JsonObject } from '
|
|
20
|
+
import { Being, isInvitation, isSilence, isWord, wordOf } from 'nervur';
|
|
21
|
+
import type { Asker, JsonObject } from 'nervur';
|
|
22
22
|
|
|
23
23
|
// One subscription, as she files it: her own id for the relation, who asked
|
|
24
24
|
// for it, and what to ask them.
|
package/dock/grants.ts
CHANGED
|
@@ -48,7 +48,7 @@ const token = () => {
|
|
|
48
48
|
// that traded for it.
|
|
49
49
|
export type Grant = { identity: string; ward: string; client: string; exp: number };
|
|
50
50
|
type Kept = { access: Record<string, Grant>; refresh: Record<string, Grant> };
|
|
51
|
-
export type Tokens = { access_token: string; token_type: 'Bearer'; expires_in: number; refresh_token: string; scope: '
|
|
51
|
+
export type Tokens = { access_token: string; token_type: 'Bearer'; expires_in: number; refresh_token: string; scope: 'nervur' };
|
|
52
52
|
|
|
53
53
|
export class Grants extends Faculty {
|
|
54
54
|
static override cells = { ...Faculty.cells, access: {}, refresh: {} };
|
|
@@ -71,7 +71,7 @@ export class Grants extends Faculty {
|
|
|
71
71
|
this.kept.refresh[refresh_token] = { identity, ward, client, exp: this.now() + REFRESH_TTL };
|
|
72
72
|
this.sweep();
|
|
73
73
|
await this.persist();
|
|
74
|
-
return { access_token, token_type: 'Bearer', expires_in: ACCESS_TTL / 1000, refresh_token, scope: '
|
|
74
|
+
return { access_token, token_type: 'Bearer', expires_in: ACCESS_TTL / 1000, refresh_token, scope: 'nervur' };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// Rotated: the old one is gone with the new one's birth. Null is a token
|
package/dock/http2.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { HOSTS, answered, provider, request, type Apns } from './apns.ts';
|
|
|
23
23
|
// which app is being rung. A box holding none is a box that rings no
|
|
24
24
|
// iPhones, which is every box but a bell's.
|
|
25
25
|
export function apnsOf(env: Record<string, string | undefined>): Apns | null {
|
|
26
|
-
const {
|
|
26
|
+
const { NERVUR_APNS_KEY: key, NERVUR_APNS_KEY_ID: keyId, NERVUR_APNS_TEAM: teamId, NERVUR_APNS_TOPIC: topic } = env;
|
|
27
27
|
return key && keyId && teamId && topic ? { key, keyId, teamId, topic } : null;
|
|
28
28
|
}
|
|
29
29
|
|
package/dock/index.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
// Which names a box lends is the terrain's word; which ward may ask for one
|
|
7
7
|
// is the harbor's, decided in `lendFor`, and a ward whose code came from a
|
|
8
8
|
// stranger is lent nothing.
|
|
9
|
-
import type { Harbor, Lend } from '
|
|
10
|
-
import type { JsonObject } from '
|
|
11
|
-
import { isInvitation } from '
|
|
9
|
+
import type { Harbor, Lend } from 'nervur/harbor';
|
|
10
|
+
import type { JsonObject } from 'nervur';
|
|
11
|
+
import { isInvitation } from 'nervur';
|
|
12
12
|
import { Faculty } from './faculty.ts';
|
|
13
13
|
import { Console, CONSOLE } from './console.ts';
|
|
14
14
|
import { Local } from './local.ts';
|
package/dock/local.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// can reach it. The desk asks `verify` at her standing, as she asks any way
|
|
15
15
|
// in.
|
|
16
16
|
import { Faculty } from './faculty.ts';
|
|
17
|
-
import type { JsonObject } from '
|
|
17
|
+
import type { JsonObject } from 'nervur';
|
|
18
18
|
import { VERIFY, type Verified } from '../beings/way.ts';
|
|
19
19
|
|
|
20
20
|
// The name the dock ward lends her under. A box with no local side lends no
|
package/dock/location.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// blueprint and the answer a box that cannot gives, and a terrain that can
|
|
5
5
|
// subclasses it. A box with no way at all boots her not at all, and a being
|
|
6
6
|
// who asks for the name is lent nothing.
|
|
7
|
-
import type { JsonObject } from '
|
|
7
|
+
import type { JsonObject } from 'nervur';
|
|
8
8
|
import { Faculty } from './faculty.ts';
|
|
9
9
|
|
|
10
10
|
export type Where = { lat: number; lng: number; accuracy?: number; at: number };
|
package/dock/notifications.ts
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
// is kept so that it never leaves the device at all. This one opens
|
|
22
22
|
// banners, and if the process that draws them were ever turned against her
|
|
23
23
|
// it would cost her a line of text rather than her world.
|
|
24
|
-
import { arithmetic } from '
|
|
25
|
-
import type { JsonObject } from '
|
|
24
|
+
import { arithmetic } from 'nervur/ward';
|
|
25
|
+
import type { JsonObject } from 'nervur';
|
|
26
26
|
import { Faculty } from './faculty.ts';
|
|
27
27
|
|
|
28
28
|
// A key is thirty two bytes of the platform's own randomness, as every seed
|
package/dock/push.ts
CHANGED
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
// The rings are live objects and not values, so they are not cells: a
|
|
13
13
|
// terrain subclasses and builds its own in `rings`, out of what its
|
|
14
14
|
// environment and this being's cells give it.
|
|
15
|
-
import { OWNER } from '
|
|
16
|
-
import { arithmetic } from '
|
|
17
|
-
import type { Asker, JsonObject, OccupantRecord } from '
|
|
15
|
+
import { OWNER } from 'nervur';
|
|
16
|
+
import { arithmetic } from 'nervur/ward';
|
|
17
|
+
import type { Asker, JsonObject, OccupantRecord } from 'nervur';
|
|
18
18
|
import { Faculty } from './faculty.ts';
|
|
19
19
|
import { mintVapid } from './webpush.ts';
|
|
20
20
|
|
|
@@ -68,7 +68,7 @@ export const SEAL = 4096;
|
|
|
68
68
|
// object is shown as it is when they are not.
|
|
69
69
|
export function banner(o: JsonObject): Line {
|
|
70
70
|
const text = (v: unknown) => (typeof v === 'string' && v.trim() ? v.trim() : '');
|
|
71
|
-
const title = text(o.title) || text(o.from) || '
|
|
71
|
+
const title = text(o.title) || text(o.from) || 'Nervur';
|
|
72
72
|
const body =
|
|
73
73
|
text(o.body) ||
|
|
74
74
|
text(o.said) ||
|
package/dock/service.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
//
|
|
6
6
|
// Why there is one at all. Apple and Google accept a push only when it is
|
|
7
7
|
// signed with the key of the team that published the app, so a world's
|
|
8
|
-
// droplet cannot ring the
|
|
8
|
+
// droplet cannot ring the Nervur app however much its human wants it to: the
|
|
9
9
|
// key belongs to whoever publishes the app and to nobody else. So a world's
|
|
10
10
|
// world hands the ring on, a token and a sealed banner, to a service the
|
|
11
11
|
// publisher runs. It is the one server the app has. An estate that ships
|
package/dock/timer.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// One method knows a terrain, `arm`, and a subclass replaces it: a
|
|
20
20
|
// `setTimeout` here, the object's storage alarm on a worker. Nothing else in
|
|
21
21
|
// her reads a platform.
|
|
22
|
-
import type { JsonObject } from '
|
|
22
|
+
import type { JsonObject } from 'nervur';
|
|
23
23
|
import { Faculty, type Woke } from './faculty.ts';
|
|
24
24
|
|
|
25
25
|
const MINUTE = 60_000;
|
package/harbor/browser.ts
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
// lease: an app has one harbor and nothing else can open its files. The
|
|
10
10
|
// classes are the estate's beings, handed in with the bundle, plus whatever
|
|
11
11
|
// a page hands in beside them.
|
|
12
|
-
import type { BeingClass } from '
|
|
12
|
+
import type { BeingClass } from 'nervur';
|
|
13
13
|
import { User, Desk, Avatar, Presence, Courier } from '../beings/index.ts';
|
|
14
|
-
import { Harbor, dial, type Dialer, type Lend, type Store } from '
|
|
14
|
+
import { Harbor, dial, type Dialer, type Lend, type Store } from 'nervur/harbor';
|
|
15
15
|
import { FACULTY_CLASSES, settled, stand } from '../dock/index.ts';
|
|
16
16
|
import { Idb } from './idb.ts';
|
|
17
17
|
|
|
@@ -26,10 +26,10 @@ export class BrowserHarbor extends Harbor {
|
|
|
26
26
|
// `lend` is what this box lends the beings of the wards it hosts: a name
|
|
27
27
|
// to an invitation on a being of its own ward. `stand` builds one; a bare
|
|
28
28
|
// tab hands none and every name answers null.
|
|
29
|
-
constructor(store: string | Store = '
|
|
29
|
+
constructor(store: string | Store = 'nervur', classes: Record<string, BeingClass> = {}, lend?: Lend) {
|
|
30
30
|
const s = typeof store === 'string' ? new Idb(store) : store;
|
|
31
31
|
super(s, async () => ({ ...BUILT_IN, ...classes }), lend);
|
|
32
|
-
this.name = typeof store === 'string' ? store : '
|
|
32
|
+
this.name = typeof store === 'string' ? store : 'nervur';
|
|
33
33
|
this.#locked = typeof store === 'string';
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -83,7 +83,7 @@ export class BrowserHarbor extends Harbor {
|
|
|
83
83
|
const locks = (globalThis.navigator as Navigator | undefined)?.locks;
|
|
84
84
|
if (!locks) return; // no web locks on this terrain: nothing vouches, as in the memory harbor
|
|
85
85
|
const granted = await new Promise<boolean>((ok) => {
|
|
86
|
-
void locks.request(`
|
|
86
|
+
void locks.request(`nervur:${this.name}`, { ifAvailable: true }, (lock) => {
|
|
87
87
|
if (!lock) {
|
|
88
88
|
ok(false);
|
|
89
89
|
return;
|
package/harbor/capacitor.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { SecureStorage, KeychainAccess } from '@aparajita/capacitor-secure-stora
|
|
|
16
16
|
import { Geolocation } from '@capacitor/geolocation';
|
|
17
17
|
import { LocalNotifications } from '@capacitor/local-notifications';
|
|
18
18
|
import { PushNotifications } from '@capacitor/push-notifications';
|
|
19
|
-
import type { BeingClass, JsonObject } from '
|
|
19
|
+
import type { BeingClass, JsonObject } from 'nervur';
|
|
20
20
|
import { LOCATION, NOTIFICATIONS, Location, Notifications, type Token, type Where } from '../dock/index.ts';
|
|
21
21
|
import { BrowserHarbor } from './browser.ts';
|
|
22
22
|
import { Sealed, type Files, type Secrets } from './sealed.ts';
|
|
@@ -162,7 +162,7 @@ export function phoneEar(sandbox = false, within = 10_000, named: { bell?: strin
|
|
|
162
162
|
// The app's one harbor, booted, lending the phone's faculties to its wards,
|
|
163
163
|
// told `wake` every time the app comes to the foreground, since a phone
|
|
164
164
|
// asleep loses its sockets silently.
|
|
165
|
-
export async function nativeHarbor(name = '
|
|
165
|
+
export async function nativeHarbor(name = 'nervur', classes: Record<string, BeingClass> = {}): Promise<BrowserHarbor> {
|
|
166
166
|
const h = new BrowserHarbor(await Native.open(name), { ...PHONE_FACULTIES, ...classes });
|
|
167
167
|
await h.stand(phoneLent);
|
|
168
168
|
await h.boot();
|
package/harbor/disk.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// tab/index.ts the classes for the tab, served bundled by the web route: human/web.ts
|
|
13
13
|
// design/ the face this world wears: tokens.css, fonts.css, fonts/, served by the web route
|
|
14
14
|
// wards/<name>/ seed, rows/, ward.json, or one sealed
|
|
15
|
-
// blob when the daemon holds
|
|
15
|
+
// blob when the daemon holds NERVUR_SEED_KEY: see files.ts
|
|
16
16
|
// reach.json the directory's hints
|
|
17
17
|
import { mkdir, readFile, writeFile, unlink, stat } from 'node:fs/promises';
|
|
18
18
|
import { existsSync } from 'node:fs';
|
|
@@ -20,20 +20,20 @@ import { join, resolve, isAbsolute } from 'node:path';
|
|
|
20
20
|
import { pathToFileURL } from 'node:url';
|
|
21
21
|
import { register } from 'node:module';
|
|
22
22
|
import process from 'node:process';
|
|
23
|
-
import type { BeingClass } from '
|
|
23
|
+
import type { BeingClass } from 'nervur';
|
|
24
24
|
import { User, Desk, Avatar, Presence, Clock, Courier } from '../beings/index.ts';
|
|
25
25
|
import { setup } from '../beings/setup.ts';
|
|
26
|
-
import { Harbor, DEFAULT_CODE, type Hosted, type Lend } from '
|
|
26
|
+
import { Harbor, DEFAULT_CODE, type Hosted, type Lend } from 'nervur/harbor';
|
|
27
27
|
import { FACULTY_CLASSES, settled, stand } from '../dock/index.ts';
|
|
28
28
|
import { Files } from './files.ts';
|
|
29
29
|
|
|
30
|
-
export type { Hosted, Bound } from '
|
|
31
|
-
export type { WardRecord } from '
|
|
30
|
+
export type { Hosted, Bound } from 'nervur/harbor';
|
|
31
|
+
export type { WardRecord } from 'nervur/harbor';
|
|
32
32
|
export const BUILT_IN: Record<string, BeingClass> = { User, Desk, Avatar, Presence, Clock, Courier, ...FACULTY_CLASSES };
|
|
33
33
|
|
|
34
34
|
// The default ward, the one a caller means when naming none: the one marked,
|
|
35
35
|
// or the one ward hosted when there is exactly one, which is every harbor an
|
|
36
|
-
// adopter stands with one `
|
|
36
|
+
// adopter stands with one `nervur init`. Several wards and none marked is
|
|
37
37
|
// refused by name, since agents and a door would otherwise hang off a
|
|
38
38
|
// guess. The dock ward is furniture, never a candidate.
|
|
39
39
|
export function defaultWard(marked: string[], hosted: string[]): string {
|
|
@@ -46,7 +46,7 @@ export function defaultWard(marked: string[], hosted: string[]): string {
|
|
|
46
46
|
const [first, ...more] = hosted.filter((n) => n !== 'dock');
|
|
47
47
|
if (first !== undefined && more.length === 0) return first;
|
|
48
48
|
const names = first === undefined ? [] : [first, ...more];
|
|
49
|
-
throw new Error(names.length === 0 ? 'this device hosts no ward: run `
|
|
49
|
+
throw new Error(names.length === 0 ? 'this device hosts no ward: run `nervur init`' : `this device hosts ${names.join(', ')} and says which is the default: nervur default <name>`);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// Folders held by a harbor in this process. The lease file names a pid, and
|
|
@@ -146,7 +146,7 @@ export class DiskHarbor extends Harbor {
|
|
|
146
146
|
// The key the environment gives, the edge's name for it: from the
|
|
147
147
|
// Keychain through the app that spawned this daemon, or nothing on a
|
|
148
148
|
// droplet, whose folder stays plain under its file modes.
|
|
149
|
-
super(new Files(abs, process.env.
|
|
149
|
+
super(new Files(abs, process.env.NERVUR_SEED_KEY), async (rec) => ({ ...BUILT_IN, ...own, ...(await loadClasses(isAbsolute(rec.code) ? rec.code : join(abs, rec.code))) }), lend);
|
|
150
150
|
this.dir = abs;
|
|
151
151
|
}
|
|
152
152
|
|
package/harbor/edge/edge.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// per request, and a held socket keeps it awake.
|
|
10
10
|
//
|
|
11
11
|
// Its owner door is a route, not a socket: the platform has no local
|
|
12
|
-
// process, so the root is whoever holds `
|
|
12
|
+
// process, so the root is whoever holds `NERVUR_ROOT`, a platform secret, and
|
|
13
13
|
// the root's asks arrive as one POST under it. That is the device's own
|
|
14
14
|
// rule on this terrain, as file permissions are on a disk. The first thing
|
|
15
15
|
// a root does is invite an owner on the ward's pk, and from then on the
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
// those pages are painted with. It also holds what this terrain lends, since
|
|
31
31
|
// a worker stands a box ward like every other terrain: the box's state has
|
|
32
32
|
// one home everywhere, and what differs is which faculties that ward lends.
|
|
33
|
-
import type { BeingClass } from '
|
|
34
|
-
import { isSilence } from '
|
|
33
|
+
import type { BeingClass } from 'nervur';
|
|
34
|
+
import { isSilence } from 'nervur';
|
|
35
35
|
import { User, Desk, Avatar, Clock } from '../../beings/index.ts';
|
|
36
36
|
import { setup } from '../../beings/setup.ts';
|
|
37
|
-
import { Harbor, Socket as Held } from '
|
|
37
|
+
import { Harbor, Socket as Held } from 'nervur/harbor';
|
|
38
38
|
import { quoRoute } from '../quo.ts';
|
|
39
39
|
import { webRoute, type Folder } from '../../human/web.ts';
|
|
40
40
|
import { DOCK, TIMER, Console, facultyOf, settled, stand } from '../../dock/index.ts';
|
|
@@ -45,7 +45,7 @@ import { apiRoute } from '../../api/route.ts';
|
|
|
45
45
|
import { mcpRoute, type Routes } from '../../mcp/route.ts';
|
|
46
46
|
import { McpHttp } from '../../mcp/http.ts';
|
|
47
47
|
import { Exchange } from '../../mcp/allow.ts';
|
|
48
|
-
import type { Invitation } from '
|
|
48
|
+
import type { Invitation } from 'nervur';
|
|
49
49
|
import { DurableStorage, danceInStorage, folderInStorage, settingsInStorage, wearInStorage } from './storage.ts';
|
|
50
50
|
import { LENT, type Deployed, type Given, type Settings, type SettingsStore } from './given.ts';
|
|
51
51
|
import { sealKey } from '../seal.ts';
|
|
@@ -82,8 +82,8 @@ export class EdgeHarbor extends Harbor {
|
|
|
82
82
|
// says nothing, so it stands no ward of its own, as a command on a disk
|
|
83
83
|
// folder stands none.
|
|
84
84
|
static async open(state: State, env: Env, deployed: Deployed = {}): Promise<EdgeHarbor> {
|
|
85
|
-
if (!env.
|
|
86
|
-
const harbor = new EdgeHarbor(new DurableStorage(state.storage, await sealKey(env.
|
|
85
|
+
if (!env.NERVUR_SEED_KEY) throw new Error('no NERVUR_SEED_KEY: a seed is never kept plain on the edge');
|
|
86
|
+
const harbor = new EdgeHarbor(new DurableStorage(state.storage, await sealKey(env.NERVUR_SEED_KEY)), env.NERVUR_ROOT, deployed);
|
|
87
87
|
harbor.lent = LENT;
|
|
88
88
|
return harbor;
|
|
89
89
|
}
|
package/harbor/edge/exercise.ts
CHANGED
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
// crosses the route. Down is the reach refused on both; migrate lifts seed,
|
|
7
7
|
// partition and record out of one view into the other and boots there. It
|
|
8
8
|
// reports rather than throws, so the worker hands the list back and Node
|
|
9
|
-
// asserts on it. Only with `
|
|
10
|
-
import { conform, conformStore, conformReach } from '
|
|
11
|
-
import { request as byRequest } from '
|
|
12
|
-
import type { World, Handle, Census } from '
|
|
13
|
-
import { Printer, Shop, Customer, Echo, Member } from '
|
|
14
|
-
import type { BeingClass, Cells, Invitation, JsonObject } from '
|
|
9
|
+
// asserts on it. Only with `NERVUR_EXERCISE` set, which a deployment never sets.
|
|
10
|
+
import { conform, conformStore, conformReach } from 'nervur/conformance';
|
|
11
|
+
import { request as byRequest } from 'nervur/harbor';
|
|
12
|
+
import type { World, Handle, Census } from 'nervur/conformance';
|
|
13
|
+
import { Printer, Shop, Customer, Echo, Member } from 'nervur/conformance';
|
|
14
|
+
import type { BeingClass, Cells, Invitation, JsonObject } from 'nervur';
|
|
15
15
|
import { EdgeHarbor } from './edge.ts';
|
|
16
16
|
import { DurableStorage } from './storage.ts';
|
|
17
17
|
import { ROW_CEILING } from './given.ts';
|
|
18
|
-
import { told } from '
|
|
18
|
+
import { told } from 'nervur';
|
|
19
19
|
import { sealKey } from '../seal.ts';
|
|
20
|
-
import type { Hosted } from '
|
|
20
|
+
import type { Hosted } from 'nervur/harbor';
|
|
21
21
|
import type { State, Env } from './platform.d.ts';
|
|
22
22
|
|
|
23
23
|
export type Result = { name: string; skip?: string; error?: string };
|
|
@@ -38,7 +38,7 @@ const DEPLOYED = { classes: { Printer, Shop, Customer, Echo, Member } satisfies
|
|
|
38
38
|
const subs = new Map<string, EdgeHarbor>();
|
|
39
39
|
|
|
40
40
|
async function pair(state: State, env: Env, run: number): Promise<{ harbors: EdgeHarbor[]; names: string[] }> {
|
|
41
|
-
const key = await sealKey(env.
|
|
41
|
+
const key = await sealKey(env.NERVUR_SEED_KEY ?? '');
|
|
42
42
|
const names = [`a-${run}-${Date.now()}`, `b-${run}-${Date.now()}`];
|
|
43
43
|
const harbors = names.map((n) => new EdgeHarbor(new DurableStorage(state.storage, key, `x:${n}:`), undefined, DEPLOYED));
|
|
44
44
|
for (const [i, h] of harbors.entries()) {
|
|
@@ -163,7 +163,7 @@ export async function exercise(request: Request, base: string, path: string, sta
|
|
|
163
163
|
const test = (name: string, opts: { skip?: string | false }, fn: () => Promise<void> | void) => {
|
|
164
164
|
queued.push({ name, skip: opts.skip ?? false, fn });
|
|
165
165
|
};
|
|
166
|
-
const key = await sealKey(env.
|
|
166
|
+
const key = await sealKey(env.NERVUR_SEED_KEY ?? '');
|
|
167
167
|
let views = 0;
|
|
168
168
|
conformStore('durable storage', async () => new DurableStorage(state.storage, key, `s:${views++}:${Date.now()}:`), { test });
|
|
169
169
|
let lines = 0;
|
|
@@ -189,7 +189,7 @@ export async function exercise(request: Request, base: string, path: string, sta
|
|
|
189
189
|
// the same refusal. That the number a deployment runs under is the
|
|
190
190
|
// platform's own is the line below it, which asks the store directly.
|
|
191
191
|
test('[edge] a row past the object s ceiling is refused, the arrival that wrote it fails at the door, and she stands at what is kept', {}, async () => {
|
|
192
|
-
const key = await sealKey(env.
|
|
192
|
+
const key = await sealKey(env.NERVUR_SEED_KEY ?? '');
|
|
193
193
|
const small = 8_000;
|
|
194
194
|
const h = new EdgeHarbor(new DurableStorage(state.storage, key, `c:${Date.now()}:`, small), undefined, DEPLOYED);
|
|
195
195
|
await h.ready();
|
package/harbor/edge/given.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// reconfigures a box without redeploying it. The design a world wears is
|
|
18
18
|
// rows beside it, one per file, reached through `Folder` like every other
|
|
19
19
|
// terrain's.
|
|
20
|
-
import type { BeingClass } from '
|
|
20
|
+
import type { BeingClass } from 'nervur';
|
|
21
21
|
import { GRANTS } from '../../dock/grants.ts';
|
|
22
22
|
import { TIMER } from '../../dock/index.ts';
|
|
23
23
|
import type { Apps, Folder } from '../../human/web.ts';
|
|
@@ -24,7 +24,7 @@ export type Storage = Rows & {
|
|
|
24
24
|
export type State = { id: { toString(): string; name?: string }; storage: Storage };
|
|
25
25
|
export type Stub = { fetch(input: string | Request, init?: RequestInit): Promise<Response> };
|
|
26
26
|
export type Namespace = { idFromName(name: string): unknown; get(id: unknown): Stub };
|
|
27
|
-
export type Env = { HARBOR: Namespace;
|
|
27
|
+
export type Env = { HARBOR: Namespace; NERVUR_SEED_KEY?: string; NERVUR_ROOT?: string; NERVUR_EXERCISE?: string };
|
|
28
28
|
// The server end of a WebSocketPair: the standard surface plus accept.
|
|
29
29
|
export type ServerSocket = { accept(): void; readyState: number; binaryType: string; send(data: string | Uint8Array): void; close(): void; addEventListener(type: string, fn: (e: never) => void): void };
|
|
30
30
|
declare global {
|
package/harbor/edge/storage.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// value would write every being in it down whenever any one was asked.
|
|
8
8
|
//
|
|
9
9
|
// The seed is kept sealed under a
|
|
10
|
-
// key from the platform's secrets, `
|
|
10
|
+
// key from the platform's secrets, `NERVUR_SEED_KEY`, with the seal in
|
|
11
11
|
// `../seal.ts`, so the storage holds ciphertext and the secret store holds
|
|
12
12
|
// the one key, which is what the harbor document's table says the edge
|
|
13
13
|
// does. Values cross as JSON, as they do into a file, because the ward
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// own settings, under `settings`, and the design a world wears, one row per
|
|
17
17
|
// file under `design:<file>`, because the object is the whole of what this
|
|
18
18
|
// terrain has to keep anything in.
|
|
19
|
-
import { fromRows, rowsIn, rowsOf, type Kept, type Store, type WardRecord } from '
|
|
19
|
+
import { fromRows, rowsIn, rowsOf, type Kept, type Store, type WardRecord } from 'nervur/harbor';
|
|
20
20
|
import { seal, open } from '../seal.ts';
|
|
21
21
|
import { emptyDance, type Dance, type Store as DanceStore } from '../../mcp/oauth.ts';
|
|
22
22
|
import type { Folder } from '../../human/web.ts';
|
package/harbor/edge/worker.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// edge is `<origin>/h/<name>/quo`, and its health `<origin>/h/<name>/health`.
|
|
6
6
|
// `wrangler.toml` beside this file names the class and the secrets.
|
|
7
7
|
//
|
|
8
|
-
// One thing lives here for the terrain test alone: with `
|
|
8
|
+
// One thing lives here for the terrain test alone: with `NERVUR_EXERCISE` set,
|
|
9
9
|
// which no deployment sets, `/exercise` runs the library's conformance
|
|
10
10
|
// suite inside the platform against two harbors in this one object, over
|
|
11
11
|
// two prefixed views of its storage, reaching each other by request
|
|
@@ -55,7 +55,7 @@ export class Quo {
|
|
|
55
55
|
// Where this harbor answers, as the world outside sees it: the routes a
|
|
56
56
|
// page hands its tab are these unless a root has named public ones.
|
|
57
57
|
const base = `${url.origin}/h/${m[1]}`;
|
|
58
|
-
if (this.env.
|
|
58
|
+
if (this.env.NERVUR_EXERCISE && (path === '/exercise' || path.startsWith('/x/'))) return exercise(request, base, path, this.state, this.env);
|
|
59
59
|
return (await this.harbor()).fetch(request, path, base);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# The edge harbor as a worker. Deploy from `dock/` with
|
|
2
2
|
# npx wrangler deploy --config harbor/edge/wrangler.toml
|
|
3
3
|
# and set the two secrets once, never in this file:
|
|
4
|
-
# npx wrangler secret put
|
|
5
|
-
# npx wrangler secret put
|
|
6
|
-
name = "
|
|
4
|
+
# npx wrangler secret put NERVUR_SEED_KEY --config harbor/edge/wrangler.toml 32 bytes as hex
|
|
5
|
+
# npx wrangler secret put NERVUR_ROOT --config harbor/edge/wrangler.toml the root's bearer
|
|
6
|
+
name = "nervur-edge"
|
|
7
7
|
main = "worker.ts"
|
|
8
8
|
compatibility_date = "2026-09-01"
|
|
9
9
|
# A deployed worker answers on the account's workers.dev subdomain; a custom
|
package/harbor/files.ts
CHANGED
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
import { mkdir, readFile, writeFile, rename, readdir, rm, chmod } from 'node:fs/promises';
|
|
34
34
|
import { existsSync } from 'node:fs';
|
|
35
35
|
import { join } from 'node:path';
|
|
36
|
-
import { arithmetic } from '
|
|
37
|
-
import { HEAD, fromRows, rowsIn, rowsOf, type Kept, type Store, type WardRecord } from '
|
|
36
|
+
import { arithmetic } from 'nervur/ward';
|
|
37
|
+
import { HEAD, fromRows, rowsIn, rowsOf, type Kept, type Store, type WardRecord } from 'nervur/harbor';
|
|
38
38
|
import { sealKey, seal, open } from './seal.ts';
|
|
39
39
|
|
|
40
40
|
const { hex, unhex } = arithmetic;
|
package/harbor/http.ts
CHANGED
|
@@ -29,8 +29,8 @@ import { createServer as createHttp, type Server as HttpServer } from 'node:http
|
|
|
29
29
|
import { Readable } from 'node:stream';
|
|
30
30
|
import { WebSocketServer } from 'ws';
|
|
31
31
|
import type { IncomingMessage } from 'node:http';
|
|
32
|
-
import { Socket as Held } from '
|
|
33
|
-
import type { Dialer } from '
|
|
32
|
+
import { Socket as Held } from 'nervur/harbor';
|
|
33
|
+
import type { Dialer } from 'nervur/harbor';
|
|
34
34
|
import type { DiskHarbor } from './disk.ts';
|
|
35
35
|
|
|
36
36
|
export type Handler = (req: Request, rest: string) => Response | undefined | Promise<Response | undefined>;
|
package/harbor/idb.ts
CHANGED
|
Binary file
|
package/harbor/quo.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// own door in `http.ts`, and a `WebSocketPair` at the edge, in the harbor
|
|
14
14
|
// there. What a dialer's socket becomes once it is held is the library's
|
|
15
15
|
// `Socket` on both.
|
|
16
|
-
import { SUITE } from '
|
|
16
|
+
import { SUITE } from 'nervur/harbor';
|
|
17
17
|
import { readAll, type Handler } from './http.ts';
|
|
18
18
|
|
|
19
19
|
// What this route asks of the harbor it answers for: one ask delivered to a
|
package/harbor/resolve.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// How a class file the harbor folder holds finds its packages. The folder
|
|
3
3
|
// is the device's, not a package: it has no node_modules, and a class in it
|
|
4
|
-
// that imports
|
|
4
|
+
// that imports `nervur` would otherwise fail to resolve from where
|
|
5
5
|
// it sits. This is a module resolution hook, registered once by the disk
|
|
6
6
|
// harbor: a bare specifier that does not resolve from a file outside any
|
|
7
7
|
// node_modules is resolved again from where the dock itself is installed,
|
package/harbor/seal.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// environment, the phone under a key from the Keychain. AES-GCM under a
|
|
6
6
|
// 32-byte key, a fresh nonce each time, nonce and ciphertext together as
|
|
7
7
|
// hex. WebCrypto only, so it runs wherever a store does.
|
|
8
|
-
import { arithmetic } from '
|
|
8
|
+
import { arithmetic } from 'nervur/ward';
|
|
9
9
|
|
|
10
10
|
const { hex, unhex } = arithmetic;
|
|
11
11
|
// Bytes as the platform's crypto wants them: over a plain ArrayBuffer.
|