@quo-systems/dock 0.2.3 → 0.2.4
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/beings/quo-dock.md +6 -0
- package/beings/user.ts +20 -6
- package/dist/beings/user.d.ts +24 -0
- package/dist/beings/user.js +20 -6
- package/dist/harbor/capacitor.d.ts +16 -0
- package/dist/harbor/capacitor.js +135 -0
- package/dist/harbor/disk.js +8 -3
- package/dist/harbor/edge/edge.js +2 -1
- package/dist/harbor/edge/exercise.js +2 -1
- package/dist/harbor/edge/storage.d.ts +0 -3
- package/dist/harbor/edge/storage.js +6 -25
- package/dist/harbor/files.d.ts +2 -1
- package/dist/harbor/files.js +87 -22
- package/dist/harbor/seal.d.ts +3 -0
- package/dist/harbor/seal.js +25 -0
- package/dist/human/html.js +3 -1
- package/dist/human/local.d.ts +10 -0
- package/dist/human/local.js +10 -0
- package/dist/human/screen.js +24 -16
- package/dist/human/tab.d.ts +1 -0
- package/dist/human/tab.js +59 -3
- package/dist/human/web.d.ts +1 -0
- package/dist/human/web.js +27 -3
- package/harbor/capacitor.ts +142 -0
- package/harbor/disk.ts +8 -3
- package/harbor/edge/edge.ts +2 -1
- package/harbor/edge/exercise.ts +2 -1
- package/harbor/edge/storage.ts +6 -25
- package/harbor/files.ts +79 -19
- package/harbor/quo-harbor.md +54 -14
- package/harbor/seal.ts +26 -0
- package/human/html.ts +3 -1
- package/human/local.ts +26 -0
- package/human/quo-human.md +56 -10
- package/human/screen.ts +19 -13
- package/human/tab.ts +50 -5
- package/human/web.ts +27 -4
- package/package.json +13 -2
package/human/web.ts
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
24
24
|
import { existsSync } from 'node:fs';
|
|
25
25
|
import { fileURLToPath } from 'node:url';
|
|
26
|
+
import { join } from 'node:path';
|
|
27
|
+
import process from 'node:process';
|
|
26
28
|
import { build } from 'esbuild';
|
|
27
29
|
import type { DiskHarbor, Hosted } from '../harbor/disk.ts';
|
|
28
30
|
import { door } from './door.ts';
|
|
@@ -33,16 +35,28 @@ export type WebOptions = {
|
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
// The paths under `/web` that are the exchange's, never a ward's name.
|
|
36
|
-
const RESERVED_PATHS = new Set(['allow', 'tab.js']);
|
|
38
|
+
const RESERVED_PATHS = new Set(['allow', 'tab.js', 'beings.js']);
|
|
39
|
+
|
|
40
|
+
// The world's code for the tab: a module in the harbor folder, the twin of
|
|
41
|
+
// `classes/index.ts`, exporting by name the classes the tab boots into its
|
|
42
|
+
// local ward for a world of this harbor. Served bundled as `beings.js` on
|
|
43
|
+
// this origin, and one origin is one world's code.
|
|
44
|
+
export const TAB_CODE = 'tab/index.ts';
|
|
37
45
|
|
|
38
46
|
export function webRoute(harbor: DiskHarbor, o: WebOptions): (req: IncomingMessage, res: ServerResponse, rest: string) => Promise<boolean> {
|
|
39
47
|
const tabEntry = () => {
|
|
40
48
|
const js = fileURLToPath(new URL('./tab.js', import.meta.url));
|
|
41
49
|
return existsSync(js) ? js : fileURLToPath(new URL('./tab.ts', import.meta.url));
|
|
42
50
|
};
|
|
51
|
+
const beingsEntry = join(harbor.dir, TAB_CODE);
|
|
52
|
+
const bundled = (entry: string) =>
|
|
53
|
+
// the entry may sit in a harbor folder with no node_modules of its own, as on a droplet whose
|
|
54
|
+
// estate folder is the working directory: what it imports is resolved from there too
|
|
55
|
+
build({ entryPoints: [entry], bundle: true, format: 'esm', platform: 'browser', target: 'es2023', write: false, nodePaths: [join(process.cwd(), 'node_modules')] }).then((out) => out.outputFiles[0]!.text);
|
|
43
56
|
let bundle: Promise<string> | undefined;
|
|
44
|
-
const built = () =>
|
|
45
|
-
|
|
57
|
+
const built = () => (bundle ??= bundled(tabEntry()));
|
|
58
|
+
let beings: Promise<string> | undefined;
|
|
59
|
+
const builtBeings = () => (beings ??= bundled(beingsEntry));
|
|
46
60
|
const quoOrigin = (() => {
|
|
47
61
|
try {
|
|
48
62
|
const u = new URL(o.at.quo);
|
|
@@ -71,7 +85,7 @@ export function webRoute(harbor: DiskHarbor, o: WebOptions): (req: IncomingMessa
|
|
|
71
85
|
};
|
|
72
86
|
const wards = () => Object.fromEntries([...harbor.wards].map(([n, h]) => [n, { pk: h.pk, public: publicOf(h) !== null }]));
|
|
73
87
|
const tab = (ward?: string) => {
|
|
74
|
-
const cfg = { quo: o.at.quo, web: o.at.web, wards: wards(), ...(ward ? { ward } : {}) };
|
|
88
|
+
const cfg = { quo: o.at.quo, web: o.at.web, wards: wards(), beings: existsSync(beingsEntry), ...(ward ? { ward } : {}) };
|
|
75
89
|
return `<script id="quo" type="application/json">${JSON.stringify(cfg).replace(/</g, '\\u003c')}</script><script type="module" src="${o.at.web}/tab.js"></script>`;
|
|
76
90
|
};
|
|
77
91
|
return async (req, res, rest) => {
|
|
@@ -88,6 +102,13 @@ export function webRoute(harbor: DiskHarbor, o: WebOptions): (req: IncomingMessa
|
|
|
88
102
|
res.end(await built());
|
|
89
103
|
return true;
|
|
90
104
|
}
|
|
105
|
+
// the world's code for the tab, when the harbor folder holds any; a harbor with none has no such path
|
|
106
|
+
if (rest === '/beings.js' && req.method === 'GET') {
|
|
107
|
+
if (!existsSync(beingsEntry)) return false;
|
|
108
|
+
res.writeHead(200, { 'content-type': 'text/javascript; charset=utf-8', 'cache-control': 'no-store' });
|
|
109
|
+
res.end(await builtBeings());
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
91
112
|
const wardName = parts[0] ?? '';
|
|
92
113
|
if (!wardName || RESERVED_PATHS.has(wardName)) return false;
|
|
93
114
|
const hosted = harbor.wards.get(wardName);
|
|
@@ -110,6 +131,8 @@ const CSS = [
|
|
|
110
131
|
'header,main{background:var(--bg);color:var(--fg);font-family:var(--font)}header{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem}header .notice{width:100%;margin:0}',
|
|
111
132
|
'input,select,textarea,button{font:inherit;padding:.4rem;margin:.2rem;border-radius:var(--radius)}button{background:var(--accent);color:#fff;border:0;padding:.4rem .9rem}',
|
|
112
133
|
'fieldset{border:1px solid color-mix(in srgb,currentColor 20%,transparent);border-radius:var(--radius);margin:.5rem 0}',
|
|
134
|
+
// a being of the world running in the tab: her own section under the far page
|
|
135
|
+
'section.local{border-top:1px solid color-mix(in srgb,currentColor 15%,transparent);margin:1.5rem 0;padding-top:.5rem}section.local header:empty{display:none}',
|
|
113
136
|
'section.standing{background:var(--bg);color:var(--fg);font-family:var(--font);border-left:4px solid var(--accent);border-radius:var(--radius);padding:.25rem 1rem;margin:1.5rem 0}section.standing h2{display:flex;align-items:center;gap:.5rem;font-size:1.1rem}img.logo{height:1.6rem}',
|
|
114
137
|
'table{border-collapse:collapse}td,th{padding:.15rem .5rem;text-align:left}.answer{margin:.5rem 0 1rem;padding:.5rem;border-left:3px solid var(--accent)}.answer.error{border-color:#c33}.answer.silence,.answer.word,.answer.unreached{border-color:#c93}pre{padding:.75rem;overflow:auto}',
|
|
115
138
|
// a page in the grammar: regions, roles, cards
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quo-systems/dock",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "The dock: what every estate on Quo needs and nobody writes twice. A daemon and the quo command, the front desk, the user being and the avatar, harbors on disk, in a tab and on the edge, the model sides and the screen.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"quo",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"types": "./dist/harbor/browser.d.ts",
|
|
32
32
|
"default": "./dist/harbor/browser.js"
|
|
33
33
|
},
|
|
34
|
+
"./harbor/capacitor": {
|
|
35
|
+
"types": "./dist/harbor/capacitor.d.ts",
|
|
36
|
+
"default": "./dist/harbor/capacitor.js"
|
|
37
|
+
},
|
|
34
38
|
"./cli/daemon": {
|
|
35
39
|
"types": "./dist/cli/daemon.d.ts",
|
|
36
40
|
"default": "./dist/cli/daemon.js"
|
|
@@ -55,6 +59,10 @@
|
|
|
55
59
|
"types": "./dist/human/html.d.ts",
|
|
56
60
|
"default": "./dist/human/html.js"
|
|
57
61
|
},
|
|
62
|
+
"./human/local": {
|
|
63
|
+
"types": "./dist/human/local.d.ts",
|
|
64
|
+
"default": "./dist/human/local.js"
|
|
65
|
+
},
|
|
58
66
|
"./harbor/edge/worker": {
|
|
59
67
|
"types": "./dist/harbor/edge/worker.d.ts",
|
|
60
68
|
"default": "./dist/harbor/edge/worker.js"
|
|
@@ -67,8 +75,11 @@
|
|
|
67
75
|
"prepublishOnly": "cd ../.. && npm run check && npm run check:terrain"
|
|
68
76
|
},
|
|
69
77
|
"dependencies": {
|
|
78
|
+
"@aparajita/capacitor-secure-storage": "^8.0.0",
|
|
79
|
+
"@capacitor/core": "^8.5.1",
|
|
80
|
+
"@capacitor/filesystem": "^8.1.3",
|
|
70
81
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
71
|
-
"@quo-systems/quo": "^0.2.
|
|
82
|
+
"@quo-systems/quo": "^0.2.4",
|
|
72
83
|
"esbuild": "^0.28.2",
|
|
73
84
|
"ws": "^8.21.3"
|
|
74
85
|
},
|