@factoidal/core 0.7.1 → 0.10.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/CHANGELOG.md +503 -1
- package/NOTICE +2 -21
- package/README.md +117 -993
- package/api.d.ts +53 -0
- package/api.js +5 -0
- package/api.mjs +56 -0
- package/bin/engine.mjs +38 -19
- package/bin/factoidal.mjs +512 -66
- package/bin/pack.mjs +37 -0
- package/bin/serve-worker.mjs +32 -0
- package/bin/serve.mjs +423 -0
- package/bin/store-worker-host.mjs +1 -1
- package/bin/store.mjs +1 -1
- package/browser.d.ts +110 -507
- package/browser.js +151 -2257
- package/docs/fuseki-replacement.md +108 -0
- package/fn.d.ts +24 -95
- package/fn.js +104 -150
- package/index.d.ts +598 -259
- package/index.js +4 -234
- package/index.mjs +176 -84
- package/l4-assets/l4factoidal.js +47 -7
- package/l4-assets/l4factoidal.mjs +1 -1
- package/l4-assets/l4factoidal.wasm +0 -0
- package/l4-assets/version.json +11 -7
- package/lib/api.mjs +2300 -0
- package/lib/browser-engine.mjs +69 -0
- package/lib/dataset.mjs +377 -0
- package/lib/delta-log-hosts.mjs +191 -0
- package/lib/lean-entry.mjs +204 -0
- package/lib/pure.mjs +98 -0
- package/lib/store.mjs +115 -0
- package/lib/version.mjs +5 -0
- package/lws/README.md +97 -0
- package/lws/server.mjs +331 -0
- package/package.json +59 -61
- package/rdfjs.js +5 -536
- package/rdfjs.mjs +594 -0
- package/sample-store.d.ts +8 -16
- package/sample-store.mjs +39 -29
- package/solid/client/README.md +100 -0
- package/solid/client/index.mjs +277 -0
- package/solid/server/README.md +96 -0
- package/solid/server/index.mjs +317 -0
- package/store-host/deno.mjs +8 -0
- package/store-host/index.mjs +12 -0
- package/store-host/node.mjs +8 -0
- package/xmpp/README.md +107 -0
- package/xmpp/index.mjs +229 -0
- package/browser-wasm.js +0 -872
- package/factoidal-npm-entry.js +0 -15477
- package/factoidal-npm-entry.wasm.assets/code-5a7fc68f2ab1323718b8.wasm +0 -0
- package/factoidal-npm-entry.wasm.js +0 -455
- package/factoidal.js +0 -13118
- package/factoidal.wasm.assets/code-bbe6099bfb5b10c4c3ab.wasm +0 -0
- package/factoidal.wasm.js +0 -457
- package/hacl-init.js +0 -92
- package/hacl-wasm/FStar.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum25519_51.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum_Base.wasm +0 -0
- package/hacl-wasm/Hacl_Curve25519_51.wasm +0 -0
- package/hacl-wasm/Hacl_Ed25519.wasm +0 -0
- package/hacl-wasm/Hacl_Ed25519_PrecompTable.wasm +0 -0
- package/hacl-wasm/Hacl_Hash_Base.wasm +0 -0
- package/hacl-wasm/Hacl_Hash_SHA2.wasm +0 -0
- package/hacl-wasm/Hacl_IntTypes_Intrinsics.wasm +0 -0
- package/hacl-wasm/LowStar_Endianness.wasm +0 -0
- package/hacl-wasm/WasmSupport.wasm +0 -0
- package/hacl-wasm/api.js +0 -775
- package/hacl-wasm/api.json +0 -3787
- package/hacl-wasm/layouts.json +0 -1
- package/hacl-wasm/loader.js +0 -568
- package/hacl-wasm/shell.js +0 -12
- package/l4-core.d.ts +0 -159
- package/l4-core.js +0 -188
- package/l4.d.ts +0 -50
- package/l4.js +0 -104
- package/lib/api.js +0 -2300
- package/lib/engine-js.js +0 -165
- package/lib/engine-wasm.js +0 -300
- package/sample-store/CURRENT +0 -1
- package/sample-store/gen-1/manifest.sbm2 +0 -0
- package/sample-store/gen-1/manifest.tsv +0 -14
- package/sample-store/gen-1/predicate-0.ibk3 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.oli2.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-1.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.oli2.merkle +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.sri2.merkle +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-3.ibk3 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.tli1.merkle +0 -2
- package/sample-store/gen-1/predicate-5.ibk3 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-7.ibk3 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.oli2.merkle +0 -2
- package/sample-store/gen-1/predicate-7.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-7.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.sri2.merkle +0 -3
- package/sample-store/gen-1/predicate-9.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.tli1.merkle +0 -2
- package/select.d.ts +0 -116
- package/select.js +0 -492
- package/version.json +0 -102
- package/wasm.d.ts +0 -130
- package/wasm.js +0 -158
package/xmpp/index.mjs
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// factoidal/xmpp — a functional-programming-style API over
|
|
2
|
+
// `L4Factoidal.XMPP` (formal/lean4/L4Factoidal/XMPP/README.md), the
|
|
3
|
+
// GC3-targeting XMPP implementation in Lean 4, served through the same
|
|
4
|
+
// wasm dispatch ABI as the rest of the Lean engine
|
|
5
|
+
// (formal/lean4/Wasm/Dispatch.lean, formal/lean4/Wasm/Ops/Xmpp.lean).
|
|
6
|
+
//
|
|
7
|
+
// Design record: formal/lean4/L4Factoidal/XMPP/README.md
|
|
8
|
+
//
|
|
9
|
+
// WHAT "FUNCTIONAL-PROGRAMMING-STYLE" MEANS HERE, CONCRETELY
|
|
10
|
+
// - Every exported function is pure data in, pure data out: plain
|
|
11
|
+
// strings/objects/arrays, no classes, no mutable instances to hold.
|
|
12
|
+
// - No exceptions for an EXPECTED outcome. A malformed JID, a stanza
|
|
13
|
+
// that isn't message/presence/iq, an unknown negotiation stage —
|
|
14
|
+
// these are ordinary answers, not exceptional control flow, so
|
|
15
|
+
// every function returns a `{ok: true, value}` or
|
|
16
|
+
// `{ok: false, error, unknownOp}` result (a Result/Either shape),
|
|
17
|
+
// never throws for them. The one thing that still throws is a
|
|
18
|
+
// genuine host/environment failure (the wasm module won't load at
|
|
19
|
+
// all) — see `loadXmppEngine()`.
|
|
20
|
+
// - Immutable results: nothing returned here is later mutated by this
|
|
21
|
+
// module. Build a new value; don't hand back something to poke at.
|
|
22
|
+
//
|
|
23
|
+
// WHAT THIS COVERS (matches exactly what `L4Factoidal.XMPP` implements
|
|
24
|
+
// today, 2026-09-07 — see the design record's "Status" section):
|
|
25
|
+
// - RFC 7622 JID parsing/rendering (`parseJid`, `renderJid`)
|
|
26
|
+
// - RFC 6120 stream header parsing/rendering (`parseStreamHeader`,
|
|
27
|
+
// `renderStreamHeader`) — tolerates the leading `<?xml ...?>`
|
|
28
|
+
// declaration real servers send (caught testing against a live
|
|
29
|
+
// ejabberd instance; see the design record)
|
|
30
|
+
// - RFC 6120 `<stream:features>` negotiation (`featuresFor`) — the
|
|
31
|
+
// TLS-then-SASL-then-bind ordering is a proved Lean theorem, not
|
|
32
|
+
// just this JS wrapper's behaviour
|
|
33
|
+
// - stanza parsing (`parseStanza`) for message/presence/iq
|
|
34
|
+
//
|
|
35
|
+
// WHAT THIS DOES NOT COVER YET, ON PURPOSE (ask for the op with
|
|
36
|
+
// `xmppOpsAvailable()`'s companion `ops` reflection before relying on
|
|
37
|
+
// it; an absent op means the resolved wasm predates it, not that this
|
|
38
|
+
// wrapper forgot it):
|
|
39
|
+
// - stanza construction FROM JSON (payload reconstruction needs a
|
|
40
|
+
// sibling-node XML parser the Lean side doesn't have yet)
|
|
41
|
+
// - GC3 itself (still an unfinished upstream XSF spec)
|
|
42
|
+
// - SASL/SCRAM computation (message FORMAT only exists so far; no
|
|
43
|
+
// HACL* HMAC-SHA-256 binding yet — see the design record's crypto
|
|
44
|
+
// section)
|
|
45
|
+
// - MUC/MIX interop modules
|
|
46
|
+
|
|
47
|
+
import { loadEngine } from '../bin/engine.mjs'
|
|
48
|
+
|
|
49
|
+
/** The XMPP op names this module calls. */
|
|
50
|
+
export const XMPP_OPS = [
|
|
51
|
+
'xmppJidParse',
|
|
52
|
+
'xmppJidRender',
|
|
53
|
+
'xmppStreamHeaderParse',
|
|
54
|
+
'xmppStreamHeaderRender',
|
|
55
|
+
'xmppFeaturesFor',
|
|
56
|
+
'xmppStanzaParse'
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
function isUnknownOp (error) {
|
|
60
|
+
const text = error && error.message ? String(error.message) : String(error)
|
|
61
|
+
return text.indexOf('unknown op') >= 0
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Load the engine handle this module's functions need. Exposed so a
|
|
66
|
+
* caller can load it once and pass it to every call via `options.engine`
|
|
67
|
+
* instead of paying the load cost per call — the one place in this
|
|
68
|
+
* module where "just call the function" isn't free, so it isn't hidden.
|
|
69
|
+
*
|
|
70
|
+
* @returns {Promise<object>} an engine handle with a `.call(op, args)` method
|
|
71
|
+
* @throws if the wasm module cannot be resolved or loaded at all — a
|
|
72
|
+
* host/environment failure, not a protocol-level outcome, so this is
|
|
73
|
+
* the one thing in this module that DOES throw
|
|
74
|
+
*/
|
|
75
|
+
export async function loadXmppEngine () {
|
|
76
|
+
return loadEngine()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Whether the loaded engine carries the XMPP ops at all — protects
|
|
81
|
+
* against a resolved wasm bundle built before they existed.
|
|
82
|
+
*
|
|
83
|
+
* @param {object} [options]
|
|
84
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
85
|
+
* @returns {Promise<{available: boolean, missing: string[]}>}
|
|
86
|
+
*/
|
|
87
|
+
export async function xmppOpsAvailable (options = {}) {
|
|
88
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
89
|
+
let names
|
|
90
|
+
try {
|
|
91
|
+
names = engine.call('ops', []).ops
|
|
92
|
+
} catch (_error) {
|
|
93
|
+
return { available: false, missing: XMPP_OPS.slice() }
|
|
94
|
+
}
|
|
95
|
+
const missing = XMPP_OPS.filter((op) => !names.includes(op))
|
|
96
|
+
return { available: missing.length === 0, missing }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Call one op, converting the engine's throw-on-`{ok:false}` convention
|
|
100
|
+
* into a Result value instead — the point of this module's shape. */
|
|
101
|
+
function callOp (engine, op, args) {
|
|
102
|
+
try {
|
|
103
|
+
return engine.call(op, args)
|
|
104
|
+
} catch (error) {
|
|
105
|
+
return { ok: false, error: String((error && error.message) || error), unknownOp: isUnknownOp(error) }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Parse an RFC 7622 JID string.
|
|
111
|
+
*
|
|
112
|
+
* Structural + length well-formedness only (per RFC 7622 §3.1); PRECIS
|
|
113
|
+
* enforcement (RFC 8264/8265 — Unicode normalisation, case folding,
|
|
114
|
+
* disallowed codepoints) is not implemented on the Lean side yet, so a
|
|
115
|
+
* string with disallowed characters but the right shape parses as
|
|
116
|
+
* `wellFormed: true`. This is a stated engine gap, not a wrapper bug.
|
|
117
|
+
*
|
|
118
|
+
* @param {string} jid
|
|
119
|
+
* @param {object} [options]
|
|
120
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
121
|
+
* @returns {Promise<{ok: true, value: {localpart: string|null,
|
|
122
|
+
* domainpart: string, resourcepart: string|null, wellFormed: boolean}}
|
|
123
|
+
* | {ok: false, error: string, unknownOp: boolean}>}
|
|
124
|
+
*/
|
|
125
|
+
export async function parseJid (jid, options = {}) {
|
|
126
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
127
|
+
const result = callOp(engine, 'xmppJidParse', [String(jid)])
|
|
128
|
+
if (result.ok === false) return result
|
|
129
|
+
const { ok, ...value } = result
|
|
130
|
+
return { ok: true, value }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Render a JID from its parts back to a string.
|
|
135
|
+
*
|
|
136
|
+
* @param {{localpart?: string|null, domainpart: string, resourcepart?: string|null}} parts
|
|
137
|
+
* @param {object} [options]
|
|
138
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
139
|
+
* @returns {Promise<{ok: true, value: string} | {ok: false, error: string, unknownOp: boolean}>}
|
|
140
|
+
*/
|
|
141
|
+
export async function renderJid (parts, options = {}) {
|
|
142
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
143
|
+
const result = callOp(engine, 'xmppJidRender', [JSON.stringify(parts)])
|
|
144
|
+
if (result.ok === false) return result
|
|
145
|
+
return { ok: true, value: result.jid }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Parse an RFC 6120 `<stream:stream ...>` opening tag. Unlike an
|
|
150
|
+
* ordinary stanza this element is never closed until the connection
|
|
151
|
+
* ends, so `rest` is the unconsumed remainder of the input (features,
|
|
152
|
+
* stanzas, and eventually `</stream:stream>`) for the caller to parse
|
|
153
|
+
* separately.
|
|
154
|
+
*
|
|
155
|
+
* @param {string} xml
|
|
156
|
+
* @param {object} [options]
|
|
157
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
158
|
+
* @returns {Promise<{ok: true, value: {from: string|null, to: string|null,
|
|
159
|
+
* id: string|null, version: string|null, lang: string|null, rest: string}}
|
|
160
|
+
* | {ok: false, error: string, unknownOp: boolean}>}
|
|
161
|
+
*/
|
|
162
|
+
export async function parseStreamHeader (xml, options = {}) {
|
|
163
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
164
|
+
const result = callOp(engine, 'xmppStreamHeaderParse', [String(xml)])
|
|
165
|
+
if (result.ok === false) return result
|
|
166
|
+
const { ok, ...value } = result
|
|
167
|
+
return { ok: true, value }
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Render an RFC 6120 stream header back to its opening-tag XML.
|
|
172
|
+
*
|
|
173
|
+
* @param {{from?: string|null, to?: string|null, id?: string|null,
|
|
174
|
+
* version?: string|null, lang?: string|null}} header
|
|
175
|
+
* @param {object} [options]
|
|
176
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
177
|
+
* @returns {Promise<{ok: true, value: string} | {ok: false, error: string, unknownOp: boolean}>}
|
|
178
|
+
*/
|
|
179
|
+
export async function renderStreamHeader (header, options = {}) {
|
|
180
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
181
|
+
const result = callOp(engine, 'xmppStreamHeaderRender', [JSON.stringify(header)])
|
|
182
|
+
if (result.ok === false) return result
|
|
183
|
+
return { ok: true, value: result.xml }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* What to advertise in `<stream:features>` at a given negotiation stage.
|
|
188
|
+
* The RFC 6120 ordering (STARTTLS only pre-TLS, SASL mechanisms only
|
|
189
|
+
* post-TLS, bind/session only once authenticated) is a proved theorem
|
|
190
|
+
* on the Lean side (`Core.featuresFor_startTls_iff_preTls` etc.) — this
|
|
191
|
+
* function cannot be called into producing a value that violates it,
|
|
192
|
+
* because no such value exists to return.
|
|
193
|
+
*
|
|
194
|
+
* @param {'preTls'|'postTls'|'authenticated'|'bound'} stage
|
|
195
|
+
* @param {string[]} [mechanisms] SASL mechanism names to offer at `postTls`
|
|
196
|
+
* @param {object} [options]
|
|
197
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
198
|
+
* @returns {Promise<{ok: true, value: {startTlsRequired: 'required'|'optional'|null,
|
|
199
|
+
* saslMechanisms: string[], canBind: boolean, canSession: boolean, xml: string}}
|
|
200
|
+
* | {ok: false, error: string, unknownOp: boolean}>}
|
|
201
|
+
*/
|
|
202
|
+
export async function featuresFor (stage, mechanisms = [], options = {}) {
|
|
203
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
204
|
+
const result = callOp(engine, 'xmppFeaturesFor', [JSON.stringify({ stage, mechanisms })])
|
|
205
|
+
if (result.ok === false) return result
|
|
206
|
+
const { ok, ...value } = result
|
|
207
|
+
return { ok: true, value }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Parse a complete `message`/`presence`/`iq` stanza. Payload children
|
|
212
|
+
* are returned as their serialized XML fragment (`payloadXml`), not a
|
|
213
|
+
* structured tree — see the module header for why stanza construction
|
|
214
|
+
* from JSON isn't offered yet.
|
|
215
|
+
*
|
|
216
|
+
* @param {string} xml
|
|
217
|
+
* @param {object} [options]
|
|
218
|
+
* @param {object} [options.engine] an engine handle to reuse
|
|
219
|
+
* @returns {Promise<{ok: true, value: {kind: 'message'|'presence'|'iq',
|
|
220
|
+
* id: string|null, from: string|null, to: string|null, type: string|null,
|
|
221
|
+
* payloadXml: string}} | {ok: false, error: string, unknownOp: boolean}>}
|
|
222
|
+
*/
|
|
223
|
+
export async function parseStanza (xml, options = {}) {
|
|
224
|
+
const engine = options.engine !== undefined ? options.engine : await loadXmppEngine()
|
|
225
|
+
const result = callOp(engine, 'xmppStanzaParse', [String(xml)])
|
|
226
|
+
if (result.ok === false) return result
|
|
227
|
+
const { ok, ...value } = result
|
|
228
|
+
return { ok: true, value }
|
|
229
|
+
}
|