@volter/world-core 3.0.163 → 3.0.165

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.
Files changed (74) hide show
  1. package/dist/generated/pack-facts.json +44 -3660
  2. package/dist/pack-facts.cjs +4 -4
  3. package/dist/src/browser-session.d.ts +7 -1
  4. package/dist/src/browser-session.js +21 -10
  5. package/dist/src/browser.d.ts +4 -0
  6. package/dist/src/browser.js +10 -0
  7. package/dist/src/derived-core.d.ts +46 -6
  8. package/dist/src/derived-core.js +60 -13
  9. package/dist/src/derived-real.js +159 -5
  10. package/dist/src/derived.d.ts +1 -1
  11. package/dist/src/events.d.ts +6 -3
  12. package/dist/src/events.js +52 -7
  13. package/dist/src/executor.d.ts +2 -2
  14. package/dist/src/executor.js +13 -0
  15. package/dist/src/file-response.d.ts +6 -2
  16. package/dist/src/file-response.js +29 -5
  17. package/dist/src/git/index.d.ts +1 -0
  18. package/dist/src/git/index.js +1 -0
  19. package/dist/src/git/smart-http-client.d.ts +28 -0
  20. package/dist/src/git/smart-http-client.js +95 -0
  21. package/dist/src/git/smart-http.d.ts +3 -0
  22. package/dist/src/git/smart-http.js +9 -0
  23. package/dist/src/head.d.ts +16 -1
  24. package/dist/src/head.js +52 -7
  25. package/dist/src/html.d.ts +29 -0
  26. package/dist/src/html.js +64 -0
  27. package/dist/src/index.d.ts +5 -2
  28. package/dist/src/index.js +5 -1
  29. package/dist/src/managed-database.d.ts +4 -2
  30. package/dist/src/managed-database.js +1 -0
  31. package/dist/src/media-header.d.ts +34 -0
  32. package/dist/src/media-header.js +129 -0
  33. package/dist/src/pack-fetch.d.ts +24 -3
  34. package/dist/src/pack-fetch.js +155 -96
  35. package/dist/src/pack-paths.d.ts +2 -3
  36. package/dist/src/pack-paths.js +3 -13
  37. package/dist/src/packRegistry.d.ts +17 -1
  38. package/dist/src/request-body.d.ts +2 -3
  39. package/dist/src/request-body.js +2 -3
  40. package/dist/src/runtime.d.ts +4 -1
  41. package/dist/src/runtime.js +5 -1
  42. package/dist/src/serve-http.d.ts +2 -2
  43. package/dist/src/serve-http.js +104 -19
  44. package/dist/src/smtp-server.d.ts +78 -0
  45. package/dist/src/smtp-server.js +160 -0
  46. package/dist/src/smtp.d.ts +29 -11
  47. package/dist/src/smtp.js +221 -52
  48. package/generated/pack-facts.json +44 -3660
  49. package/pack-facts.cjs +4 -4
  50. package/package.json +4 -2
  51. package/src/browser-session.ts +17 -5
  52. package/src/browser.ts +10 -0
  53. package/src/derived-core.ts +77 -19
  54. package/src/derived-real.ts +131 -4
  55. package/src/derived.ts +2 -2
  56. package/src/events.ts +54 -9
  57. package/src/executor.ts +13 -2
  58. package/src/file-response.ts +28 -6
  59. package/src/git/index.ts +1 -0
  60. package/src/git/smart-http-client.ts +99 -0
  61. package/src/git/smart-http.ts +7 -0
  62. package/src/head.ts +37 -6
  63. package/src/html.ts +72 -0
  64. package/src/index.ts +6 -2
  65. package/src/managed-database.ts +4 -3
  66. package/src/media-header.ts +108 -0
  67. package/src/pack-fetch.ts +142 -87
  68. package/src/pack-paths.ts +3 -11
  69. package/src/packRegistry.ts +9 -1
  70. package/src/request-body.ts +2 -3
  71. package/src/runtime.ts +5 -1
  72. package/src/serve-http.ts +81 -19
  73. package/src/smtp-server.ts +166 -0
  74. package/src/smtp.ts +199 -53
@@ -56,9 +56,10 @@ export type { TwinResource } from './serve.js';
56
56
  export { passwordHash, personOf, personWith, recordPerson, shownPersonFields, type Person } from './people.js';
57
57
  export { EngineDatabaseError, EngineUnavailableError, quoteIdent } from './managed-database.js';
58
58
  export type { Batch as EngineBatch, ManagedDatabase, Statement as EngineStatement, StatementResult as EngineStatementResult } from './managed-database.js';
59
- export type { Mail, SmtpRoute } from './smtp.js';
59
+ export type { Mail, MailReply } from './smtp.js';
60
60
  export * as s3 from './s3/wire.js';
61
61
  export * as xml from './xml.js';
62
+ export * as html from './html.js';
62
63
  export * as clickhouse from './clickhouse/index.js';
63
64
  export { sampleFromSchema } from './schema-sample.js';
64
65
  export * as openaiWire from './openai-wire.js';
@@ -67,8 +68,10 @@ export * as protobuf from './protobuf.js';
67
68
  export * as grpc from './grpc-wire.js';
68
69
  export { acceptH2Connection, type H2Handler, type Http1Handler } from './h2.js';
69
70
  export { placeholderPng } from './placeholder-image.js';
71
+ export { imageDimensions, readImageHeader, readMp4Header } from './media-header.js';
70
72
  export { presignSigV4, signSigV4, verifySigV4, type SigV4Verdict } from './sigv4.js';
71
73
  export * as redis from './redis/index.js';
74
+ export * as smtpServer from './smtp-server.js';
72
75
  export * as mysql from './mysql/index.js';
73
76
  export * as live from './live/index.js';
74
77
  export * as mongodb from './mongodb/index.js';
@@ -76,7 +79,7 @@ export * as git from './git/index.js';
76
79
  export { parseScenarioDocument, scenarioFaultResult, ScenarioEngine, ScenarioError } from './scenario.js';
77
80
  export type { PackScenarioAdapter, ScenarioDecision, ScenarioDocument, ScenarioExtractorSpec, ScenarioFault, ScenarioFaultResult, ScenarioFeatures, ScenarioHandler, ScenarioMatcher, ScenarioMissRecord, ScenarioStatus } from './scenario.js';
78
81
  export { verifyAttestationBundle } from './attestation.js';
79
- export { browserSessionToken, startBrowserSession, endBrowserSession } from './browser-session.js';
82
+ export { cookieOf, signedIn, browserSessionToken, startBrowserSession, endBrowserSession } from './browser-session.js';
80
83
  export { readHostPort } from './host-port.js';
81
84
  export { assertBrowserName, browserOrigin, validateBrowserState, validateBrowserStorageState, validateBrowserContext, browserAcceptLanguage, cookieMatchesHost, type BrowserCookie, type BrowserState, type BrowserStorageState, type BrowserContext, type BrowserIndexedDB } from './browser-state.js';
82
85
  export * as managedOriginalInputs from './managed-original-inputs.js';
package/dist/src/index.js CHANGED
@@ -51,6 +51,8 @@ export { EngineDatabaseError, EngineUnavailableError, quoteIdent } from "./manag
51
51
  export * as s3 from "./s3/wire.js";
52
52
  // Generic strict XML grammar; vendor interpretation remains in its consumer.
53
53
  export * as xml from "./xml.js";
54
+ // Generic WHATWG HTML grammar; what a pack keeps of received HTML remains the pack's policy.
55
+ export * as html from "./html.js";
54
56
  export * as clickhouse from "./clickhouse/index.js";
55
57
  export { sampleFromSchema } from "./schema-sample.js";
56
58
  export * as openaiWire from "./openai-wire.js";
@@ -59,8 +61,10 @@ export * as protobuf from "./protobuf.js";
59
61
  export * as grpc from "./grpc-wire.js";
60
62
  export { acceptH2Connection } from "./h2.js";
61
63
  export { placeholderPng } from "./placeholder-image.js";
64
+ export { imageDimensions, readImageHeader, readMp4Header } from "./media-header.js";
62
65
  export { presignSigV4, signSigV4, verifySigV4 } from "./sigv4.js";
63
66
  export * as redis from "./redis/index.js";
67
+ export * as smtpServer from "./smtp-server.js";
64
68
  export * as mysql from "./mysql/index.js";
65
69
  export * as live from "./live/index.js";
66
70
  export * as mongodb from "./mongodb/index.js";
@@ -68,7 +72,7 @@ export * as git from "./git/index.js";
68
72
  // ── the scenario grammar (architecture, "Behaviour") ───────────────────────────────────────────
69
73
  export { parseScenarioDocument, scenarioFaultResult, ScenarioEngine, ScenarioError } from "./scenario.js";
70
74
  export { verifyAttestationBundle } from "./attestation.js";
71
- export { browserSessionToken, startBrowserSession, endBrowserSession } from "./browser-session.js";
75
+ export { cookieOf, signedIn, browserSessionToken, startBrowserSession, endBrowserSession } from "./browser-session.js";
72
76
  export { readHostPort } from "./host-port.js";
73
77
  export { assertBrowserName, browserOrigin, validateBrowserState, validateBrowserStorageState, validateBrowserContext, browserAcceptLanguage, cookieMatchesHost } from "./browser-state.js";
74
78
  export * as managedOriginalInputs from "./managed-original-inputs.js";
@@ -76,9 +76,11 @@ export declare function managedDatabase(url: string, options?: {
76
76
  * walk/journey-kit.ts), its statements sent as its client sends them: a text alone as one simple Query (a migration
77
77
  * file, a `BEGIN`), a text with values as one extended-protocol statement, the values bind parameters. A transaction it
78
78
  * opens stays open across its statements until it ends it, as on the application's own connection. Each statement's
79
- * answer is its results in Postgres's text format, untyped. */
79
+ * answer is its results in Postgres's text format, with native column type OIDs retained beside the values. */
80
80
  export type DatabaseSession = {
81
- query(text: string, values?: ReadonlyArray<string | null>): Promise<StatementResult[]>;
81
+ query(text: string, values?: ReadonlyArray<string | null>): Promise<Array<StatementResult & {
82
+ fieldTypes: number[];
83
+ }>>;
82
84
  end(): Promise<void>;
83
85
  };
84
86
  /** The World's Postgres at `url` as one connection held until `end()`. */
@@ -255,6 +255,7 @@ export async function databaseSession(url) {
255
255
  const answer = (await client.query({ text, ...(values === undefined ? {} : { values }), rowMode: 'array', types: raw }));
256
256
  return (Array.isArray(answer) ? answer : [answer]).map((r) => ({
257
257
  fields: (r.fields ?? []).map((f) => f.name),
258
+ fieldTypes: (r.fields ?? []).map((f) => f.dataTypeID),
258
259
  rows: r.rows ?? [],
259
260
  command: [r.command ?? '', r.command === 'INSERT' ? '0' : '', r.rowCount ?? ''].filter((part) => part !== '').join(' '),
260
261
  }));
@@ -0,0 +1,34 @@
1
+ type ImageType = 'image/png' | 'image/gif' | 'image/jpeg' | 'image/webp';
2
+ type Dimensions = {
3
+ width: number;
4
+ height: number;
5
+ };
6
+ type ImageHeader = Dimensions & {
7
+ jpeg?: {
8
+ frameEnd: number;
9
+ nonMarkerBytes: boolean;
10
+ standaloneMarkers: boolean;
11
+ fillBytes: boolean;
12
+ shortSegments: boolean;
13
+ };
14
+ };
15
+ /** Dimensions in a caller-declared image format, or undefined for an incomplete header. */
16
+ export declare function imageDimensions(bytes: Uint8Array, type: ImageType): ImageHeader | undefined;
17
+ /** An image's signature and dimensions, without deciding whether a vendor accepts that format or size. */
18
+ export declare function readImageHeader(bytes: Uint8Array): (ImageHeader & {
19
+ type: ImageType;
20
+ }) | undefined;
21
+ /** ISO BMFF's bounded top-level boxes and movie headers, with raw duration and 16.16 track dimensions. */
22
+ export declare function readMp4Header(bytes: Uint8Array): {
23
+ fileType: boolean;
24
+ hasMediaData: boolean;
25
+ movies: Array<{
26
+ headers: Array<{
27
+ timescale: number;
28
+ duration: number;
29
+ payloadSize: number;
30
+ }>;
31
+ tracks: Dimensions[];
32
+ }>;
33
+ };
34
+ export {};
@@ -0,0 +1,129 @@
1
+ const tag = (bytes, at) => String.fromCharCode(...bytes.subarray(at, at + 4));
2
+ /** Dimensions in a caller-declared image format, or undefined for an incomplete header. */
3
+ export function imageDimensions(bytes, type) {
4
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
5
+ if (type === 'image/png')
6
+ return bytes.length >= 24 ? { width: view.getUint32(16), height: view.getUint32(20) } : undefined;
7
+ if (type === 'image/gif')
8
+ return bytes.length >= 10 ? { width: view.getUint16(6, true), height: view.getUint16(8, true) } : undefined;
9
+ if (type === 'image/webp') {
10
+ if (bytes.length < 30)
11
+ return undefined;
12
+ const chunk = tag(bytes, 12);
13
+ if (chunk === 'VP8 ')
14
+ return { width: view.getUint16(26, true) & 0x3fff, height: view.getUint16(28, true) & 0x3fff };
15
+ if (chunk === 'VP8L') {
16
+ const bits = view.getUint32(21, true);
17
+ return { width: 1 + (bits & 0x3fff), height: 1 + ((bits >>> 14) & 0x3fff) };
18
+ }
19
+ if (chunk === 'VP8X') {
20
+ const u24 = (at) => bytes[at] | (bytes[at + 1] << 8) | (bytes[at + 2] << 16);
21
+ return { width: 1 + u24(24), height: 1 + u24(27) };
22
+ }
23
+ return undefined;
24
+ }
25
+ let at = 2;
26
+ const jpeg = { frameEnd: 0, nonMarkerBytes: false, standaloneMarkers: false, fillBytes: false, shortSegments: false };
27
+ while (at + 4 <= bytes.length) {
28
+ if (bytes[at] !== 0xff) {
29
+ jpeg.nonMarkerBytes = true;
30
+ at += 1;
31
+ continue;
32
+ }
33
+ const marker = bytes[at + 1];
34
+ if (marker === 0xff) {
35
+ jpeg.fillBytes = true;
36
+ at += 1;
37
+ continue;
38
+ }
39
+ if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {
40
+ jpeg.standaloneMarkers = true;
41
+ at += 2;
42
+ continue;
43
+ }
44
+ const length = view.getUint16(at + 2);
45
+ if (length < 2)
46
+ jpeg.shortSegments = true;
47
+ if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {
48
+ return at + 9 <= bytes.length ? { width: view.getUint16(at + 7), height: view.getUint16(at + 5), jpeg: { ...jpeg, frameEnd: at + 9 } } : undefined;
49
+ }
50
+ if (marker === 0xda)
51
+ return undefined;
52
+ at += 2 + length;
53
+ }
54
+ return undefined;
55
+ }
56
+ /** An image's signature and dimensions, without deciding whether a vendor accepts that format or size. */
57
+ export function readImageHeader(bytes) {
58
+ let type;
59
+ if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47)
60
+ type = 'image/png';
61
+ else if (tag(bytes, 0).startsWith('GIF'))
62
+ type = 'image/gif';
63
+ else if (bytes[0] === 0xff && bytes[1] === 0xd8)
64
+ type = 'image/jpeg';
65
+ else if (tag(bytes, 0) === 'RIFF' && tag(bytes, 8) === 'WEBP')
66
+ type = 'image/webp';
67
+ else
68
+ return undefined;
69
+ const dimensions = imageDimensions(bytes, type);
70
+ return dimensions ? { type, ...dimensions } : undefined;
71
+ }
72
+ /** ISO BMFF's bounded top-level boxes and movie headers, with raw duration and 16.16 track dimensions. */
73
+ export function readMp4Header(bytes) {
74
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
75
+ function* boxes(from, to) {
76
+ let at = from;
77
+ while (at + 8 <= to) {
78
+ let size = view.getUint32(at);
79
+ const type = tag(bytes, at + 4);
80
+ let header = 8;
81
+ if (size === 1) {
82
+ if (at + 16 > to)
83
+ return;
84
+ size = Number(view.getBigUint64(at + 8));
85
+ header = 16;
86
+ }
87
+ if (size === 0)
88
+ size = to - at;
89
+ if (!Number.isSafeInteger(size) || size < header || size > to - at)
90
+ return;
91
+ yield { type, start: at + header, end: at + size };
92
+ at += size;
93
+ }
94
+ }
95
+ const result = { fileType: bytes.length >= 8 && tag(bytes, 4) === 'ftyp', hasMediaData: false, movies: [] };
96
+ for (const box of boxes(0, bytes.length)) {
97
+ if (box.type === 'mdat' && box.end > box.start)
98
+ result.hasMediaData = true;
99
+ if (box.type !== 'moov')
100
+ continue;
101
+ const movie = { headers: [], tracks: [] };
102
+ result.movies.push(movie);
103
+ for (const child of boxes(box.start, box.end)) {
104
+ const { type, start, end } = child;
105
+ if (type === 'mvhd' && start < end) {
106
+ const version = bytes[start];
107
+ const payloadSize = end - start;
108
+ if (version === 0 && payloadSize >= 20)
109
+ movie.headers.push({ timescale: view.getUint32(start + 12), duration: view.getUint32(start + 16), payloadSize });
110
+ if (version === 1 && payloadSize >= 32)
111
+ movie.headers.push({ timescale: view.getUint32(start + 20), duration: Number(view.getBigUint64(start + 24)), payloadSize });
112
+ }
113
+ if (type !== 'trak')
114
+ continue;
115
+ for (const track of boxes(start, end)) {
116
+ if (track.type !== 'tkhd' || track.start >= track.end)
117
+ continue;
118
+ const version = bytes[track.start];
119
+ const at = version === 1 ? track.start + 88 : version === 0 ? track.start + 76 : track.end;
120
+ if (at + 8 > track.end)
121
+ continue;
122
+ const width = view.getUint32(at) / 65536;
123
+ const height = view.getUint32(at + 4) / 65536;
124
+ movie.tracks.push({ width, height });
125
+ }
126
+ }
127
+ }
128
+ return result;
129
+ }
@@ -1,5 +1,5 @@
1
- import { type DerivedManifest, type Handler, type HandlerContext, type ScreenDecl, type VendorManifest } from './derived-core.js';
2
- import { type DerivedFetch, type DerivedSurface, type BoardFrame } from './derived.js';
1
+ import { type DerivedManifest, type Handler, type HandlerContext, type LanesDecl, type ScreenDecl, type VendorManifest } from './derived-core.js';
2
+ import { compileSurface, type DerivedFetch, type DerivedSurface, type BoardFrame } from './derived.js';
3
3
  import { type PackScenarioAdapter } from './scenario.js';
4
4
  import type { ApplicationStandIn } from './events.js';
5
5
  import { type SocketEngine } from './sockets.js';
@@ -83,13 +83,34 @@ export type PackFetchOptions = {
83
83
  clock?: () => string;
84
84
  database?: string;
85
85
  scenarioPath?: string;
86
- /** the application a walk stands in for (a life's `application` answers): this fetch's `ctx.ask` is answered by it */
86
+ /** the application a walk stands in for: this fetch's requests and declared events are answered by it */
87
87
  application?: ApplicationStandIn;
88
88
  };
89
+ /** The host a request is for: the vendor host the World's injector names, else its own. */
90
+ export declare const hostOf: (request: Request) => string;
89
91
  /** Where a workspace asked `?show=<type>:<id>` opens the record (architecture, "Workspace"): the built workspace page
90
92
  * that shows that type, its parameter the id; else the one that lists the type; else the workspace's home (its root
91
93
  * page). Every other parameter a page's path names is the asking page's, and a page that cannot be filled is passed
92
94
  * over. Undefined when nothing is asked; the path (with no `show`) otherwise. */
93
95
  export declare function shownRecord(url: URL, workspaces: ReadonlyArray<ScreenDecl>, params: Record<string, string>): string | undefined;
96
+ /** A declared World door, matched by the same normalized path for serving and response ownership. */
97
+ export declare function worldDoorMatcher<Door extends {
98
+ method: string;
99
+ path: string;
100
+ }>(doors: ReadonlyArray<Door>): (method: string, path: string) => {
101
+ door: Door;
102
+ params: Record<string, string>;
103
+ } | undefined;
104
+ /** A request with its path's repeated slashes merged, as a front that merges them routes it (the manifest's
105
+ * `mergeSlashes`); one with none is itself. */
106
+ export declare function slashesMerged(request: Request): Request;
107
+ /** The selected unit's request transformation, shared by serving and response judgment. */
108
+ export declare function unitRequestRouter(m: Pick<DerivedManifest, 'pathPrefix' | 'basePathAlias' | 'pathFromHost' | 'hostParams' | 'headerParams'>, surface: DerivedSurface, routes: ReturnType<typeof compileSurface>): (request: Request) => Request;
109
+ /** A pack's HTTP surface, as the kernel serves it from the pack's parts. */
94
110
  export declare function createPackFetch(parts: PackParts, options?: PackFetchOptions): DerivedFetch;
111
+ /** The lane selected by the vendor gateway, shared by serving and response judgment. */
112
+ export declare function laneSelector(decl: LanesDecl, lanes: Record<string, {
113
+ manifest: LanePart['manifest'];
114
+ fetch: Pick<LanePart['fetch'], 'serves' | 'contentHosts'>;
115
+ }>, rootServes?: (method: string, path: string) => boolean): (request: Request) => string | undefined;
95
116
  export declare function createVendorFetch(manifest: VendorManifest, lanes: Record<string, LanePart>): DerivedFetch;