@valancex/common 0.0.0-stage → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -2
- package/dist/announce.d.ts +25 -0
- package/dist/announce.js +39 -0
- package/dist/app.d.ts +35 -0
- package/dist/app.js +124 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.js +40 -0
- package/dist/http.d.ts +65 -0
- package/dist/http.js +188 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.js +24 -0
- package/dist/internal.d.ts +7 -0
- package/dist/internal.js +9 -0
- package/dist/model.d.ts +72 -0
- package/dist/model.js +4 -0
- package/dist/primitives.d.ts +2 -0
- package/dist/primitives.js +41 -0
- package/dist/routes.d.ts +9 -0
- package/dist/routes.js +46 -0
- package/dist/scope.d.ts +83 -0
- package/dist/scope.js +134 -0
- package/dist/server.d.ts +20 -0
- package/dist/server.js +22 -0
- package/dist/state.d.ts +13 -0
- package/dist/state.js +33 -0
- package/dist/transport.d.ts +37 -0
- package/dist/transport.js +1 -0
- package/dist/viewport.d.ts +15 -0
- package/dist/viewport.js +24 -0
- package/dist/vocabulary.d.ts +9 -0
- package/dist/vocabulary.js +3 -0
- package/package.json +75 -3
- package/types/mprx.d.ts +5 -0
package/dist/state.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// The application's state beyond the page, however it was declared: field by field (`field(type, default)`), or as a hand-built schema with a separate initial value. Both become one thing here.
|
|
2
|
+
// No Node and no Vite: the browser entry loads this too.
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
import { FIELD } from "./index.js";
|
|
5
|
+
const isField = (value) => typeof value === "object" && value !== null && FIELD in value;
|
|
6
|
+
/** The state a definition declares, or `undefined` for none. */
|
|
7
|
+
export const stateOf = (author) => {
|
|
8
|
+
const state = author?.state;
|
|
9
|
+
if (state === undefined) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const entries = Object.entries(state);
|
|
13
|
+
// A hand-built state is `{ schema, initial }` where `schema` is a Schema; a field named `schema` is a Field.
|
|
14
|
+
if (!entries.some(([, value]) => isField(value)) && "schema" in state && Schema.isSchema(state["schema"])) {
|
|
15
|
+
return { schema: state["schema"], initial: (state["initial"] ?? {}), declared: false };
|
|
16
|
+
}
|
|
17
|
+
const fields = entries.filter((entry) => isField(entry[1]));
|
|
18
|
+
return {
|
|
19
|
+
schema: Schema.Struct(Object.fromEntries(fields.map(([name, each]) => [name, each.schema]))),
|
|
20
|
+
initial: Object.fromEntries(fields.map(([name, each]) => [name, each.initial])),
|
|
21
|
+
declared: true,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/** The fields whose default is not a value of the field's own type (only for a state declared field by field). */
|
|
25
|
+
export const badDefaults = (author) => {
|
|
26
|
+
const state = stateOf(author);
|
|
27
|
+
if (state === undefined || !state.declared) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
return Object.entries(state.schema.fields)
|
|
31
|
+
.filter(([name, schema]) => !Schema.is(schema)(state.initial[name]))
|
|
32
|
+
.map(([name]) => name);
|
|
33
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Effect } from "effect";
|
|
2
|
+
export type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
3
|
+
/** Why a request did not give a value. None of them carries the response text, the address or a header: those can hold a secret. */
|
|
4
|
+
export type HttpError = {
|
|
5
|
+
readonly _tag: "Offline";
|
|
6
|
+
} | {
|
|
7
|
+
readonly _tag: "Status";
|
|
8
|
+
readonly status: number;
|
|
9
|
+
} | {
|
|
10
|
+
readonly _tag: "Decode";
|
|
11
|
+
} | {
|
|
12
|
+
readonly _tag: "Timeout";
|
|
13
|
+
} | {
|
|
14
|
+
readonly _tag: "Aborted";
|
|
15
|
+
} | {
|
|
16
|
+
readonly _tag: "TooLarge";
|
|
17
|
+
} | {
|
|
18
|
+
readonly _tag: "Unsafe";
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
};
|
|
21
|
+
/** The request as it goes out: already checked, with its final address. Headers are lower-case. */
|
|
22
|
+
export interface TransportRequest {
|
|
23
|
+
readonly method: Method;
|
|
24
|
+
readonly url: string;
|
|
25
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
26
|
+
readonly body?: string;
|
|
27
|
+
readonly timeoutMs: number;
|
|
28
|
+
}
|
|
29
|
+
/** The answer as it came back, whatever its status. Headers are lower-case. `text` is empty for no content. */
|
|
30
|
+
export interface TransportResponse {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
33
|
+
readonly text: string;
|
|
34
|
+
}
|
|
35
|
+
export type Transport = (request: TransportRequest) => Effect.Effect<TransportResponse, HttpError>;
|
|
36
|
+
/** Wraps the next transport: change the request on the way in, the answer on the way out, call `next` more than once (retry) or not at all (a cached answer). */
|
|
37
|
+
export type Interceptor = (next: Transport) => Transport;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Viewport } from "./index.js";
|
|
2
|
+
export declare const MEDIUM = 600;
|
|
3
|
+
export declare const EXPANDED = 840;
|
|
4
|
+
export declare const viewportOf: (width: number) => Viewport;
|
|
5
|
+
interface Query {
|
|
6
|
+
readonly matches: boolean;
|
|
7
|
+
addEventListener(type: "change", listener: () => void): void;
|
|
8
|
+
removeEventListener(type: "change", listener: () => void): void;
|
|
9
|
+
}
|
|
10
|
+
export interface MediaWindow {
|
|
11
|
+
matchMedia(query: string): Query;
|
|
12
|
+
}
|
|
13
|
+
/** Calls `changed` with the current class now, and again whenever it changes. Returns the function that stops watching. */
|
|
14
|
+
export declare const watchViewport: (win: MediaWindow, changed: (viewport: Viewport) => void) => (() => void);
|
|
15
|
+
export {};
|
package/dist/viewport.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const MEDIUM = 600;
|
|
2
|
+
export const EXPANDED = 840;
|
|
3
|
+
export const viewportOf = (width) => (width >= EXPANDED ? "expanded" : width >= MEDIUM ? "medium" : "compact");
|
|
4
|
+
/** Calls `changed` with the current class now, and again whenever it changes. Returns the function that stops watching. */
|
|
5
|
+
export const watchViewport = (win, changed) => {
|
|
6
|
+
const medium = win.matchMedia(`(min-width: ${MEDIUM}px)`);
|
|
7
|
+
const expanded = win.matchMedia(`(min-width: ${EXPANDED}px)`);
|
|
8
|
+
const current = () => (expanded.matches ? "expanded" : medium.matches ? "medium" : "compact");
|
|
9
|
+
let last;
|
|
10
|
+
const check = () => {
|
|
11
|
+
const now = current();
|
|
12
|
+
if (now !== last) {
|
|
13
|
+
last = now;
|
|
14
|
+
changed(now);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
medium.addEventListener("change", check);
|
|
18
|
+
expanded.addEventListener("change", check);
|
|
19
|
+
check();
|
|
20
|
+
return () => {
|
|
21
|
+
medium.removeEventListener("change", check);
|
|
22
|
+
expanded.removeEventListener("change", check);
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WebPrimitives } from "@valancex/port-web";
|
|
2
|
+
export interface Vocabulary {
|
|
3
|
+
/** The target's id (`web`). */
|
|
4
|
+
readonly target: string;
|
|
5
|
+
/** The tags, each with its props and events. */
|
|
6
|
+
readonly tags: WebPrimitives;
|
|
7
|
+
}
|
|
8
|
+
/** The web's vocabulary: HTML elements, with `class`, `theme`, `id` and `aria-*` as styling and accessibility hooks. */
|
|
9
|
+
export declare const webVocabulary: Vocabulary;
|
package/package.json
CHANGED
|
@@ -1,6 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valancex/common",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.12.0",
|
|
4
|
+
"description": "The author's side of a VALANCE application (defineApp, component, field) and the runtime the vlx build runs: the browser and server entries. What src/main.ts imports; @valancex/cli builds what it describes.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"valance",
|
|
7
|
+
"defineApp",
|
|
8
|
+
"component"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/ValanceX/Valance/tree/main/packages/common#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ValanceX/Valance/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/ValanceX/Valance.git",
|
|
17
|
+
"directory": "packages/common"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"author": "Jack Miller <jackmiller0899@gmail.com>",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=22"
|
|
24
|
+
},
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./client": {
|
|
32
|
+
"types": "./dist/client.d.ts",
|
|
33
|
+
"default": "./dist/client.js"
|
|
34
|
+
},
|
|
35
|
+
"./http": {
|
|
36
|
+
"types": "./dist/http.d.ts",
|
|
37
|
+
"default": "./dist/http.js"
|
|
38
|
+
},
|
|
39
|
+
"./internal": {
|
|
40
|
+
"types": "./dist/internal.d.ts",
|
|
41
|
+
"default": "./dist/internal.js"
|
|
42
|
+
},
|
|
43
|
+
"./package.json": "./package.json",
|
|
44
|
+
"./server": {
|
|
45
|
+
"types": "./dist/server.d.ts",
|
|
46
|
+
"default": "./dist/server.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"types": "./dist/index.d.ts",
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"types"
|
|
53
|
+
],
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public",
|
|
56
|
+
"provenance": true
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@valancex/mesh-runtime": "^0.11.0",
|
|
60
|
+
"@valancex/nexus": "^0.12.0",
|
|
61
|
+
"@valancex/port-web": "^0.4.0",
|
|
62
|
+
"@valancex/valance": "^0.12.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"effect": "^3.10.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/node": "^22.0.0",
|
|
69
|
+
"effect": "^3.10.0",
|
|
70
|
+
"typescript": "^5.6.0",
|
|
71
|
+
"vitest": "^3.2.0"
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"build": "tsc -p tsconfig.json",
|
|
75
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
76
|
+
"test": "vitest run"
|
|
77
|
+
}
|
|
6
78
|
}
|
package/types/mprx.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// What importing a template file gives the author's TypeScript: the file's address (see `Template` in src/index.ts, which this is structurally). The bundler (vite.ts) makes the import.
|
|
2
|
+
declare module "*.mprx" {
|
|
3
|
+
const template: { readonly mprx: string };
|
|
4
|
+
export default template;
|
|
5
|
+
}
|