@macula-io/ts 0.13.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/LICENSE +201 -0
- package/README.md +343 -0
- package/dist/binding.d.ts +47 -0
- package/dist/binding.js +133 -0
- package/dist/binding.js.map +1 -0
- package/dist/content.d.ts +14 -0
- package/dist/content.js +45 -0
- package/dist/content.js.map +1 -0
- package/dist/dht.d.ts +54 -0
- package/dist/dht.js +25 -0
- package/dist/dht.js.map +1 -0
- package/dist/directdial.d.ts +79 -0
- package/dist/directdial.js +76 -0
- package/dist/directdial.js.map +1 -0
- package/dist/identity.d.ts +43 -0
- package/dist/identity.js +83 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/pubsub.d.ts +55 -0
- package/dist/pubsub.js +8 -0
- package/dist/pubsub.js.map +1 -0
- package/dist/rpc.d.ts +69 -0
- package/dist/rpc.js +47 -0
- package/dist/rpc.js.map +1 -0
- package/dist/session.d.ts +453 -0
- package/dist/session.js +807 -0
- package/dist/session.js.map +1 -0
- package/dist/ucan.d.ts +108 -0
- package/dist/ucan.js +142 -0
- package/dist/ucan.js.map +1 -0
- package/package.json +57 -0
- package/prebuilds/darwin-arm64/@macula-io+ts.node +0 -0
- package/prebuilds/darwin-x64/@macula-io+ts.node +0 -0
- package/prebuilds/linux-arm64/@macula-io+ts.node +0 -0
- package/prebuilds/linux-x64/@macula-io+ts.node +0 -0
- package/prebuilds/win32-x64/@macula-io+ts.node +0 -0
package/dist/binding.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Loads the compiled N-API addon (addon/binding.cc) and re-exports its
|
|
2
|
+
// typed functions. Unlike the koffi-era version of this file, there is
|
|
3
|
+
// no runtime signature declaration here -- the addon's C++ glue already
|
|
4
|
+
// knows its own shapes, throws real JS errors on failure (no more
|
|
5
|
+
// manual errOut-array/checkErr dance), and is a single self-contained
|
|
6
|
+
// .node file (cabi/'s Go code is statically linked in via
|
|
7
|
+
// -buildmode=c-archive, not loaded separately at runtime).
|
|
8
|
+
//
|
|
9
|
+
// node-gyp-build picks, at require time, whichever of these exists:
|
|
10
|
+
// build/Release/*.node (a local dev build via `npm run build:addon:dev`)
|
|
11
|
+
// or prebuilds/<platform>-<arch>/*.node (baked in by `npm run
|
|
12
|
+
// build:prebuilds` / prebuildify, and published as part of the npm
|
|
13
|
+
// package) -- this is the whole point: a consumer installing this
|
|
14
|
+
// package from npm never runs a compiler or fetches anything, because
|
|
15
|
+
// the matching prebuild is already sitting in the downloaded tarball.
|
|
16
|
+
import { createRequire } from "node:module";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
const require = createRequire(import.meta.url);
|
|
20
|
+
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
22
|
+
const addon = require("node-gyp-build")(repoRoot);
|
|
23
|
+
export const native = {
|
|
24
|
+
identityGenerate() {
|
|
25
|
+
return addon.identityGenerate();
|
|
26
|
+
},
|
|
27
|
+
identityFromSeedBytes(seed32) {
|
|
28
|
+
if (seed32.length !== 32) {
|
|
29
|
+
throw new Error(`macula-ts: seed must be exactly 32 bytes, got ${seed32.length}`);
|
|
30
|
+
}
|
|
31
|
+
return addon.identityFromSeedBytes(seed32);
|
|
32
|
+
},
|
|
33
|
+
identityNodeId(handle) {
|
|
34
|
+
return addon.identityNodeId(handle);
|
|
35
|
+
},
|
|
36
|
+
identityPrivateBytes(handle) {
|
|
37
|
+
return addon.identityPrivateBytes(handle);
|
|
38
|
+
},
|
|
39
|
+
identityFree(handle) {
|
|
40
|
+
addon.identityFree(handle);
|
|
41
|
+
},
|
|
42
|
+
identitySign(handle, data) {
|
|
43
|
+
return addon.identitySign(handle, data);
|
|
44
|
+
},
|
|
45
|
+
sessionConnect(host, port, identityHandle) {
|
|
46
|
+
return addon.sessionConnect(host, port, identityHandle);
|
|
47
|
+
},
|
|
48
|
+
sessionRemoteAddr(handle) {
|
|
49
|
+
return addon.sessionRemoteAddr(handle);
|
|
50
|
+
},
|
|
51
|
+
sessionStationNodeId(handle) {
|
|
52
|
+
return addon.sessionStationNodeId(handle);
|
|
53
|
+
},
|
|
54
|
+
sessionClose(handle, identityHandle, reason) {
|
|
55
|
+
return addon.sessionClose(handle, identityHandle, reason);
|
|
56
|
+
},
|
|
57
|
+
sessionCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs) {
|
|
58
|
+
return addon.sessionCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs);
|
|
59
|
+
},
|
|
60
|
+
ucanMint(identityHandle, issuer, audience, capabilitiesJson, expiresAt, notBefore, nonce, factsJson, proofsJson) {
|
|
61
|
+
return addon.ucanMint(identityHandle, issuer, audience, capabilitiesJson, expiresAt, notBefore, nonce, factsJson, proofsJson);
|
|
62
|
+
},
|
|
63
|
+
ucanDecode(token) {
|
|
64
|
+
return addon.ucanDecode(token);
|
|
65
|
+
},
|
|
66
|
+
sessionCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken) {
|
|
67
|
+
return addon.sessionCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken);
|
|
68
|
+
},
|
|
69
|
+
sessionAdvertise(sessionHandle, identityHandle, realm, procedure) {
|
|
70
|
+
return addon.sessionAdvertise(sessionHandle, identityHandle, realm, procedure);
|
|
71
|
+
},
|
|
72
|
+
sessionUnadvertise(sessionHandle, identityHandle, realm, procedure) {
|
|
73
|
+
return addon.sessionUnadvertise(sessionHandle, identityHandle, realm, procedure);
|
|
74
|
+
},
|
|
75
|
+
serveWaitForCall(sessionHandle, identityHandle, realm, procedure, timeoutMs) {
|
|
76
|
+
return addon.serveWaitForCall(sessionHandle, identityHandle, realm, procedure, timeoutMs);
|
|
77
|
+
},
|
|
78
|
+
pendingCallProcedure(pendingHandle) {
|
|
79
|
+
return addon.pendingCallProcedure(pendingHandle);
|
|
80
|
+
},
|
|
81
|
+
pendingCallPayloadJson(pendingHandle) {
|
|
82
|
+
return addon.pendingCallPayloadJson(pendingHandle);
|
|
83
|
+
},
|
|
84
|
+
pendingCallReplyResult(pendingHandle, resultJson) {
|
|
85
|
+
return addon.pendingCallReplyResult(pendingHandle, resultJson);
|
|
86
|
+
},
|
|
87
|
+
pendingCallReplyError(pendingHandle, detail) {
|
|
88
|
+
return addon.pendingCallReplyError(pendingHandle, detail);
|
|
89
|
+
},
|
|
90
|
+
dhtFindRecordsByType(sessionHandle, identityHandle, recordType) {
|
|
91
|
+
return addon.dhtFindRecordsByType(sessionHandle, identityHandle, recordType);
|
|
92
|
+
},
|
|
93
|
+
dhtFindRecords(sessionHandle, identityHandle, key32) {
|
|
94
|
+
return addon.dhtFindRecords(sessionHandle, identityHandle, key32);
|
|
95
|
+
},
|
|
96
|
+
dhtFindRecord(sessionHandle, identityHandle, key32) {
|
|
97
|
+
return addon.dhtFindRecord(sessionHandle, identityHandle, key32);
|
|
98
|
+
},
|
|
99
|
+
dhtPutProcedureAdvertisement(sessionHandle, identityHandle, realm, procedure, servingStation32, ttlMs) {
|
|
100
|
+
return addon.dhtPutProcedureAdvertisement(sessionHandle, identityHandle, realm, procedure, servingStation32, ttlMs);
|
|
101
|
+
},
|
|
102
|
+
dhtPutContentAnnouncement(sessionHandle, identityHandle, mcid34, endpoint, ttlMs) {
|
|
103
|
+
return addon.dhtPutContentAnnouncement(sessionHandle, identityHandle, mcid34, endpoint, ttlMs);
|
|
104
|
+
},
|
|
105
|
+
sessionPublish(sessionHandle, identityHandle, realm, topic, payloadJson, ttlMs) {
|
|
106
|
+
return addon.sessionPublish(sessionHandle, identityHandle, realm, topic, payloadJson, ttlMs);
|
|
107
|
+
},
|
|
108
|
+
sessionSubscribeStart(sessionHandle, identityHandle, realm, topic, onEvent) {
|
|
109
|
+
return addon.sessionSubscribeStart(sessionHandle, identityHandle, realm, topic, onEvent);
|
|
110
|
+
},
|
|
111
|
+
sessionSubscribeStop(subscriptionHandle) {
|
|
112
|
+
return addon.sessionSubscribeStop(subscriptionHandle);
|
|
113
|
+
},
|
|
114
|
+
contentPut(sessionHandle, identityHandle, data, name) {
|
|
115
|
+
return addon.contentPut(sessionHandle, identityHandle, data, name);
|
|
116
|
+
},
|
|
117
|
+
contentGet(sessionHandle, identityHandle, mcidHex) {
|
|
118
|
+
return addon.contentGet(sessionHandle, identityHandle, mcidHex);
|
|
119
|
+
},
|
|
120
|
+
directdialResolve(sessionHandle, identityHandle, realm, procedure) {
|
|
121
|
+
return addon.directdialResolve(sessionHandle, identityHandle, realm, procedure);
|
|
122
|
+
},
|
|
123
|
+
directdialCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs) {
|
|
124
|
+
return addon.directdialCall(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs);
|
|
125
|
+
},
|
|
126
|
+
directdialCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken) {
|
|
127
|
+
return addon.directdialCallWithUcan(sessionHandle, identityHandle, procedure, realm, payloadJson, timeoutMs, ucanToken);
|
|
128
|
+
},
|
|
129
|
+
directdialAdvertise(sessionHandle, identityHandle, realm, procedure, ttlMs) {
|
|
130
|
+
return addon.directdialAdvertise(sessionHandle, identityHandle, realm, procedure, ttlMs);
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,wEAAwE;AACxE,kEAAkE;AAClE,sEAAsE;AACtE,0DAA0D;AAC1D,2DAA2D;AAC3D,EAAE;AACF,oEAAoE;AACpE,yEAAyE;AACzE,8DAA8D;AAC9D,mEAAmE;AACnE,kEAAkE;AAClE,sEAAsE;AACtE,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAErE,8DAA8D;AAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAkM/C,CAAC;AAQF,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gBAAgB;QACd,OAAO,KAAK,CAAC,gBAAgB,EAAE,CAAC;IAClC,CAAC;IACD,qBAAqB,CAAC,MAAkB;QACtC,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,iDAAiD,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,cAAc,CAAC,MAAc;QAC3B,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IACD,oBAAoB,CAAC,MAAc;QACjC,OAAO,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IACD,YAAY,CAAC,MAAc;QACzB,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IACD,YAAY,CAAC,MAAc,EAAE,IAAgB;QAC3C,OAAO,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,cAAc,CAAC,IAAY,EAAE,IAAY,EAAE,cAAsB;QAC/D,OAAO,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC1D,CAAC;IACD,iBAAiB,CAAC,MAAc;QAC9B,OAAO,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,oBAAoB,CAAC,MAAc;QACjC,OAAO,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IACD,YAAY,CAAC,MAAc,EAAE,cAAsB,EAAE,MAAc;QACjE,OAAO,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;IACD,WAAW,CACT,aAAqB,EACrB,cAAsB,EACtB,SAAiB,EACjB,KAA6B,EAC7B,WAAmB,EACnB,SAAiB;QAEjB,OAAO,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACpG,CAAC;IACD,QAAQ,CACN,cAAsB,EACtB,MAAc,EACd,QAAgB,EAChB,gBAAwB,EACxB,SAA6B,EAC7B,SAA6B,EAC7B,KAAa,EACb,SAA6B,EAC7B,UAA8B;QAE9B,OAAO,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAChI,CAAC;IACD,UAAU,CAAC,KAAa;QACtB,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,mBAAmB,CACjB,aAAqB,EACrB,cAAsB,EACtB,SAAiB,EACjB,KAA6B,EAC7B,WAAmB,EACnB,SAAiB,EACjB,SAAiB;QAEjB,OAAO,KAAK,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACvH,CAAC;IACD,gBAAgB,CAAC,aAAqB,EAAE,cAAsB,EAAE,KAA6B,EAAE,SAAiB;QAC9G,OAAO,KAAK,CAAC,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACjF,CAAC;IACD,kBAAkB,CAAC,aAAqB,EAAE,cAAsB,EAAE,KAA6B,EAAE,SAAiB;QAChH,OAAO,KAAK,CAAC,kBAAkB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACnF,CAAC;IACD,gBAAgB,CACd,aAAqB,EACrB,cAAsB,EACtB,KAA6B,EAC7B,SAAiB,EACjB,SAAiB;QAEjB,OAAO,KAAK,CAAC,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC5F,CAAC;IACD,oBAAoB,CAAC,aAAqB;QACxC,OAAO,KAAK,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IACD,sBAAsB,CAAC,aAAqB;QAC1C,OAAO,KAAK,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACrD,CAAC;IACD,sBAAsB,CAAC,aAAqB,EAAE,UAAkB;QAC9D,OAAO,KAAK,CAAC,sBAAsB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC;IACD,qBAAqB,CAAC,aAAqB,EAAE,MAAc;QACzD,OAAO,KAAK,CAAC,qBAAqB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;IACD,oBAAoB,CAAC,aAAqB,EAAE,cAAsB,EAAE,UAAkB;QACpF,OAAO,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IAC/E,CAAC;IACD,cAAc,CAAC,aAAqB,EAAE,cAAsB,EAAE,KAAiB;QAC7E,OAAO,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IACpE,CAAC;IACD,aAAa,CAAC,aAAqB,EAAE,cAAsB,EAAE,KAAiB;QAC5E,OAAO,KAAK,CAAC,aAAa,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IACD,4BAA4B,CAC1B,aAAqB,EACrB,cAAsB,EACtB,KAA6B,EAC7B,SAAiB,EACjB,gBAA4B,EAC5B,KAAa;QAEb,OAAO,KAAK,CAAC,4BAA4B,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACtH,CAAC;IACD,yBAAyB,CACvB,aAAqB,EACrB,cAAsB,EACtB,MAAkB,EAClB,QAAgB,EAChB,KAAa;QAEb,OAAO,KAAK,CAAC,yBAAyB,CAAC,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACjG,CAAC;IACD,cAAc,CACZ,aAAqB,EACrB,cAAsB,EACtB,KAA6B,EAC7B,KAAa,EACb,WAAmB,EACnB,KAAa;QAEb,OAAO,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAC/F,CAAC;IACD,qBAAqB,CACnB,aAAqB,EACrB,cAAsB,EACtB,KAA6B,EAC7B,KAAa,EACb,OAIS;QAET,OAAO,KAAK,CAAC,qBAAqB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3F,CAAC;IACD,oBAAoB,CAAC,kBAA0B;QAC7C,OAAO,KAAK,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;IACxD,CAAC;IACD,UAAU,CAAC,aAAqB,EAAE,cAAsB,EAAE,IAAgB,EAAE,IAAY;QACtF,OAAO,KAAK,CAAC,UAAU,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,UAAU,CAAC,aAAqB,EAAE,cAAsB,EAAE,OAAe;QACvE,OAAO,KAAK,CAAC,UAAU,CAAC,aAAa,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;IACD,iBAAiB,CAAC,aAAqB,EAAE,cAAsB,EAAE,KAA6B,EAAE,SAAiB;QAC/G,OAAO,KAAK,CAAC,iBAAiB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClF,CAAC;IACD,cAAc,CACZ,aAAqB,EACrB,cAAsB,EACtB,SAAiB,EACjB,KAA6B,EAC7B,WAAmB,EACnB,SAAiB;QAEjB,OAAO,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACvG,CAAC;IACD,sBAAsB,CACpB,aAAqB,EACrB,cAAsB,EACtB,SAAiB,EACjB,KAA6B,EAC7B,WAAmB,EACnB,SAAiB,EACjB,SAAiB;QAEjB,OAAO,KAAK,CAAC,sBAAsB,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC1H,CAAC;IACD,mBAAmB,CACjB,aAAqB,EACrB,cAAsB,EACtB,KAA6B,EAC7B,SAAiB,EACjB,KAAa;QAEb,OAAO,KAAK,CAAC,mBAAmB,CAAC,aAAa,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3F,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Thrown by Session.getContent() when the station reports the content
|
|
2
|
+
* isn't known to it (macula-go's content.ErrNotFound) -- an expected,
|
|
3
|
+
* routine outcome for a transfer mechanism with no durability
|
|
4
|
+
* guarantee, not a transport failure. Unlike DhtRecord's findRecord()
|
|
5
|
+
* (which resolves `null` for its own equivalent "not found" case),
|
|
6
|
+
* getContent() throws instead: its whole contract is "hand back the
|
|
7
|
+
* bytes or fail", and there is no sensible non-throwing value to return
|
|
8
|
+
* in place of the `Uint8Array` a caller asked for. */
|
|
9
|
+
export declare class ContentNotFoundError extends Error {
|
|
10
|
+
/** The mcid that produced this error, hex-encoded (the same string
|
|
11
|
+
* that was passed to getContent()). */
|
|
12
|
+
readonly mcid: string;
|
|
13
|
+
constructor(mcid: string);
|
|
14
|
+
}
|
package/dist/content.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Content transfer -- macula-go's content package (Put/Get), thin
|
|
2
|
+
// CALL/RESULT wrappers to reserved `_content.*` procedures sent on
|
|
3
|
+
// their OWN dedicated QUIC stream (Session.OpenDedicatedStream on the
|
|
4
|
+
// Go side), NOT the shared control stream call()/serve()/the DHT
|
|
5
|
+
// methods/subscribe() all read from -- see cabi/content.go's own doc
|
|
6
|
+
// for why Session.putContent()/getContent() (session.ts) are, unlike
|
|
7
|
+
// those, never subject to Session's same-Session exclusivity guard, and
|
|
8
|
+
// why two concurrent putContent()/getContent() calls on one Session
|
|
9
|
+
// don't race each other either (each gets its own fresh dedicated
|
|
10
|
+
// stream).
|
|
11
|
+
//
|
|
12
|
+
// IMPORTANT: this is a one-time TRANSFER mechanism, not durable object
|
|
13
|
+
// storage. A station may forget content after serving it, there is no
|
|
14
|
+
// "list what's stored here" operation, and there is no "delete"
|
|
15
|
+
// operation -- putContent()/getContent() hand a blob to a peer once,
|
|
16
|
+
// they do not give you a key-value store. Do not build anything on this
|
|
17
|
+
// SDK that assumes content survives indefinitely, or that a station is
|
|
18
|
+
// obligated to keep serving something it once accepted.
|
|
19
|
+
//
|
|
20
|
+
// mcid crosses the FFI boundary as a lowercase hex string (68 hex
|
|
21
|
+
// chars = 34 bytes: <<Version:8, Codec:8, Hash:32/binary>>, macula-go's
|
|
22
|
+
// manifest.Mcid) -- the same "raw byte identifier -> hex string"
|
|
23
|
+
// convention DhtRecord's key/version/signature already use (dht.ts),
|
|
24
|
+
// deliberately NOT rpc.ts's own "0x"-prefixed convention for bytes
|
|
25
|
+
// embedded *inside* a JSON payload -- an mcid stands on its own here,
|
|
26
|
+
// it isn't a payload field.
|
|
27
|
+
/** Thrown by Session.getContent() when the station reports the content
|
|
28
|
+
* isn't known to it (macula-go's content.ErrNotFound) -- an expected,
|
|
29
|
+
* routine outcome for a transfer mechanism with no durability
|
|
30
|
+
* guarantee, not a transport failure. Unlike DhtRecord's findRecord()
|
|
31
|
+
* (which resolves `null` for its own equivalent "not found" case),
|
|
32
|
+
* getContent() throws instead: its whole contract is "hand back the
|
|
33
|
+
* bytes or fail", and there is no sensible non-throwing value to return
|
|
34
|
+
* in place of the `Uint8Array` a caller asked for. */
|
|
35
|
+
export class ContentNotFoundError extends Error {
|
|
36
|
+
/** The mcid that produced this error, hex-encoded (the same string
|
|
37
|
+
* that was passed to getContent()). */
|
|
38
|
+
mcid;
|
|
39
|
+
constructor(mcid) {
|
|
40
|
+
super(`macula-ts: no content found for mcid ${mcid}`);
|
|
41
|
+
this.name = "ContentNotFoundError";
|
|
42
|
+
this.mcid = mcid;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,mEAAmE;AACnE,sEAAsE;AACtE,iEAAiE;AACjE,qEAAqE;AACrE,qEAAqE;AACrE,wEAAwE;AACxE,oEAAoE;AACpE,kEAAkE;AAClE,WAAW;AACX,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,gEAAgE;AAChE,qEAAqE;AACrE,wEAAwE;AACxE,uEAAuE;AACvE,wDAAwD;AACxD,EAAE;AACF,kEAAkE;AAClE,wEAAwE;AACxE,iEAAiE;AACjE,qEAAqE;AACrE,mEAAmE;AACnE,sEAAsE;AACtE,4BAA4B;AAE5B;;;;;;;sDAOsD;AACtD,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C;2CACuC;IAC9B,IAAI,CAAS;IAEtB,YAAY,IAAY;QACtB,KAAK,CAAC,wCAAwC,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/dht.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { JsonValue } from "./rpc.js";
|
|
2
|
+
/** Record type tags -- macula-go's dht.Type* constants (dht/record.go).
|
|
3
|
+
* There is no client-side constructor for StationEndpoint in macula-go
|
|
4
|
+
* (stations publish those themselves, not clients) -- it's listed here
|
|
5
|
+
* because Session.findRecord/findRecords/findRecordsByType can still
|
|
6
|
+
* return one, not because a Session.putRecord* method can build one. */
|
|
7
|
+
export declare enum DhtRecordType {
|
|
8
|
+
ProcedureAdvertisement = 6,
|
|
9
|
+
ContentAnnouncement = 17,
|
|
10
|
+
StationEndpoint = 18
|
|
11
|
+
}
|
|
12
|
+
/** A signed, TTL'd DHT record envelope -- mirrors macula-go's dht.Record
|
|
13
|
+
* (dht/record.go). `key`/`version`/`signature` are raw bytes with no
|
|
14
|
+
* native JSON shape, so they cross the FFI boundary as lowercase hex
|
|
15
|
+
* strings -- deliberately NOT rpc.ts's own "0x"-prefixed convention for
|
|
16
|
+
* bytes embedded inside a payload (see cabi/dht.go's own doc for why:
|
|
17
|
+
* these three fields never go through jsonToCbor/cborToJSON at all,
|
|
18
|
+
* wirevalue.go's "0x"-hex convention is specifically for bytes found
|
|
19
|
+
* *inside* a cbor.Value payload, which these aren't). `payload` DID go
|
|
20
|
+
* through that conversion (it's the record's own cbor.Value map) and
|
|
21
|
+
* follows rpc.ts's JsonValue rules exactly like a CALL payload does --
|
|
22
|
+
* no boolean, embedded bytes as "0x"-prefixed hex. Note that a
|
|
23
|
+
* procedure_advertisement/content_announcement's own advertiser_node/
|
|
24
|
+
* serving_station/announcer_node/mcid payload fields are themselves raw
|
|
25
|
+
* bytes on the wire (CBOR byte strings) but surface here as the SAME
|
|
26
|
+
* "0x"-prefixed hex JsonValue strings cborToJSON gives any embedded
|
|
27
|
+
* bytes -- consistent with every other payload field this SDK decodes,
|
|
28
|
+
* just called out since they look similar to this record's own
|
|
29
|
+
* top-level key/version/signature while following the other convention.
|
|
30
|
+
*
|
|
31
|
+
* This SDK does not verify a record's signature or check its expiry on
|
|
32
|
+
* the caller's behalf (matching macula-go's own FindRecord/FindRecords/
|
|
33
|
+
* FindRecordsByType, which say the same in their own doc comments) --
|
|
34
|
+
* a caller that needs to trust a record's payload must check both
|
|
35
|
+
* itself (against `key`, `signature`, and `expiresAt`) before relying
|
|
36
|
+
* on it. */
|
|
37
|
+
export interface DhtRecord {
|
|
38
|
+
readonly type: DhtRecordType | number;
|
|
39
|
+
/** Hex-encoded, 32 bytes: the envelope signer's Ed25519 public key. */
|
|
40
|
+
readonly key: string;
|
|
41
|
+
/** Hex-encoded, 16 bytes: a UUIDv7. */
|
|
42
|
+
readonly version: string;
|
|
43
|
+
/** Milliseconds since epoch. */
|
|
44
|
+
readonly createdAt: number;
|
|
45
|
+
/** Milliseconds since epoch. */
|
|
46
|
+
readonly expiresAt: number;
|
|
47
|
+
readonly payload: JsonValue;
|
|
48
|
+
/** Hex-encoded, 64 bytes. */
|
|
49
|
+
readonly signature: string;
|
|
50
|
+
}
|
|
51
|
+
/** Default TTL for a record built by Session.putProcedureAdvertisement()/
|
|
52
|
+
* putContentAnnouncement() when the caller doesn't specify one --
|
|
53
|
+
* matches macula-go's dht.DefaultTTL (48h). */
|
|
54
|
+
export declare const DHT_DEFAULT_TTL_MS: number;
|
package/dist/dht.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// DHT record shapes -- macula-go's dht package (FindRecord/FindRecords/
|
|
2
|
+
// FindRecordsByType/PutRecord), thin CALL wrappers to the mesh's own
|
|
3
|
+
// reserved `_dht.*` procedures under the DHT's own all-zero realm
|
|
4
|
+
// (threaded internally by macula-go's dht package, never passed from
|
|
5
|
+
// here -- see cabi/dht.go). Session (session.ts) is the actual FFI
|
|
6
|
+
// entry point for these, matching call()/serve()'s own shape (a
|
|
7
|
+
// Session-bound method, using that Session's own retained Identity to
|
|
8
|
+
// sign); this file holds the shapes both directions share, the same
|
|
9
|
+
// split rpc.ts has for call()/serve().
|
|
10
|
+
/** Record type tags -- macula-go's dht.Type* constants (dht/record.go).
|
|
11
|
+
* There is no client-side constructor for StationEndpoint in macula-go
|
|
12
|
+
* (stations publish those themselves, not clients) -- it's listed here
|
|
13
|
+
* because Session.findRecord/findRecords/findRecordsByType can still
|
|
14
|
+
* return one, not because a Session.putRecord* method can build one. */
|
|
15
|
+
export var DhtRecordType;
|
|
16
|
+
(function (DhtRecordType) {
|
|
17
|
+
DhtRecordType[DhtRecordType["ProcedureAdvertisement"] = 6] = "ProcedureAdvertisement";
|
|
18
|
+
DhtRecordType[DhtRecordType["ContentAnnouncement"] = 17] = "ContentAnnouncement";
|
|
19
|
+
DhtRecordType[DhtRecordType["StationEndpoint"] = 18] = "StationEndpoint";
|
|
20
|
+
})(DhtRecordType || (DhtRecordType = {}));
|
|
21
|
+
/** Default TTL for a record built by Session.putProcedureAdvertisement()/
|
|
22
|
+
* putContentAnnouncement() when the caller doesn't specify one --
|
|
23
|
+
* matches macula-go's dht.DefaultTTL (48h). */
|
|
24
|
+
export const DHT_DEFAULT_TTL_MS = 48 * 60 * 60 * 1000;
|
|
25
|
+
//# sourceMappingURL=dht.js.map
|
package/dist/dht.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dht.js","sourceRoot":"","sources":["../src/dht.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,qEAAqE;AACrE,kEAAkE;AAClE,qEAAqE;AACrE,mEAAmE;AACnE,gEAAgE;AAChE,sEAAsE;AACtE,oEAAoE;AACpE,uCAAuC;AAIvC;;;;wEAIwE;AACxE,MAAM,CAAN,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,qFAA6B,CAAA;IAC7B,gFAA0B,CAAA;IAC1B,wEAAsB,CAAA;AACxB,CAAC,EAJW,aAAa,KAAb,aAAa,QAIxB;AA0CD;;+CAE+C;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CallOptions, Session } from "./session.js";
|
|
2
|
+
/** What Session.resolveDirect() resolves with: `procedure`'s
|
|
3
|
+
* currently-advertised serving station and its dialable host/port
|
|
4
|
+
* (macula-go's `directdial.Resolve`). */
|
|
5
|
+
export interface DirectDialTarget {
|
|
6
|
+
/** Hex-encoded, 32 bytes: the resolved station's NodeID (Ed25519
|
|
7
|
+
* public key) -- the SAME identity Session.callDirect()/
|
|
8
|
+
* callDirectWithUcan() pin the one-hop dial against internally before
|
|
9
|
+
* trusting it. */
|
|
10
|
+
readonly station: string;
|
|
11
|
+
readonly host: string;
|
|
12
|
+
readonly port: number;
|
|
13
|
+
}
|
|
14
|
+
/** Options for Session.advertiseDirect(). */
|
|
15
|
+
export interface AdvertiseDirectOptions {
|
|
16
|
+
/** Same 64-character hex realm convention as CallOptions.realm --
|
|
17
|
+
* MUST match whatever realm resolveDirect()/callDirect()/
|
|
18
|
+
* callDirectWithUcan() (or the Erlang/Rust/Go equivalent) resolve
|
|
19
|
+
* under, or the two sides derive a different discovery URI and resolve
|
|
20
|
+
* comes back exactly as if this was never called at all (see
|
|
21
|
+
* directdial.go's own DiscoveryURI note). Omitted means the all-zero
|
|
22
|
+
* realm, this SDK's sole default before this option existed. */
|
|
23
|
+
realm?: string;
|
|
24
|
+
/** Milliseconds. Defaults to DHT_DEFAULT_TTL_MS (48h) -- matches
|
|
25
|
+
* macula-go's own dht.DefaultTTL, applied Go-side for ttlMs<=0 (not
|
|
26
|
+
* duplicated as a second default here; this SDK's default is threaded
|
|
27
|
+
* through explicitly instead, matching putProcedureAdvertisement's own
|
|
28
|
+
* convention). */
|
|
29
|
+
ttlMs?: number;
|
|
30
|
+
}
|
|
31
|
+
/** How long keepAdvertisedDirect() waits between re-advertise ticks, in
|
|
32
|
+
* milliseconds, when opts.intervalMs is left unset. This is a real
|
|
33
|
+
* production margin against AdvertiseDirectOptions' own 48h default TTL
|
|
34
|
+
* actually expiring between ticks -- not chosen to match macula-go's own
|
|
35
|
+
* KeepAdvertisedDirect live-test interval (1s there, only to keep that
|
|
36
|
+
* particular test fast). A caller passing a much shorter `ttlMs` should
|
|
37
|
+
* pass a correspondingly shorter `intervalMs` too; this constant does not
|
|
38
|
+
* scale itself to `opts.ttlMs`. */
|
|
39
|
+
export declare const KEEP_ADVERTISED_DIRECT_INTERVAL_MS: number;
|
|
40
|
+
/** Options for keepAdvertisedDirect(). */
|
|
41
|
+
export interface KeepAdvertisedDirectOptions extends AdvertiseDirectOptions {
|
|
42
|
+
/** Milliseconds between re-advertise ticks. Defaults to
|
|
43
|
+
* KEEP_ADVERTISED_DIRECT_INTERVAL_MS. */
|
|
44
|
+
intervalMs?: number;
|
|
45
|
+
/** Called with a tick's own thrown error when a re-advertise tick
|
|
46
|
+
* fails -- a network blip, a genuinely dead session, etc. Matches
|
|
47
|
+
* macula-go's own KeepAdvertisedDirect: a failed tick is reported, not
|
|
48
|
+
* fatal -- this loop tries again at the next interval regardless, and
|
|
49
|
+
* cannot detect or repair a dead Session on its own (a separate, larger
|
|
50
|
+
* concern this does not attempt to solve). Omit to drop the error
|
|
51
|
+
* silently. */
|
|
52
|
+
onError?: (err: unknown) => void;
|
|
53
|
+
}
|
|
54
|
+
/** Re-advertises `procedure` as direct-dial-reachable on `session` (via
|
|
55
|
+
* `session.advertiseDirect()`) immediately, then again every
|
|
56
|
+
* `opts.intervalMs`, until the returned `stop()` is called -- macula-go's
|
|
57
|
+
* own `KeepAdvertisedDirect` free function, ported here as a standalone
|
|
58
|
+
* helper rather than a Session method for the identical reason
|
|
59
|
+
* macula-go's own is a free function taking a `*connection.Session`
|
|
60
|
+
* rather than a method on one: a station's registration for a procedure
|
|
61
|
+
* does not survive the connection that sent it being replaced, so a
|
|
62
|
+
* long-lived provider needs to call `AdvertiseDirect` again on its own
|
|
63
|
+
* schedule, and it is this function's CALLER's job to decide WHICH
|
|
64
|
+
* Session that runs on. See `Session.advertiseDirect()`'s own doc for why
|
|
65
|
+
* that must NOT be a Session with an active `serve()` on it
|
|
66
|
+
* (`advertiseDirect()`'s own `PutRecord` CALL would race `serve()`'s own
|
|
67
|
+
* reads of the same shared control stream): a long-lived provider that
|
|
68
|
+
* also serves `procedure` needs a SEPARATE Session (and identity -- this
|
|
69
|
+
* fleet enforces one connection per identity, kicking whichever connects
|
|
70
|
+
* second) for that, passed here instead of the serving Session.
|
|
71
|
+
*
|
|
72
|
+
* The returned `stop()` is synchronous -- unlike `Session.serve()`'s own
|
|
73
|
+
* async `stop()`, there is no pending tick to wait out and no unadvertise
|
|
74
|
+
* step: `advertiseDirect()`'s own DHT record simply expires on its own
|
|
75
|
+
* TTL once ticks stop, matching macula-go's own `KeepAdvertisedDirect`,
|
|
76
|
+
* which has no corresponding "undo" either. Calling `stop()` more than
|
|
77
|
+
* once is a no-op. */
|
|
78
|
+
export declare function keepAdvertisedDirect(session: Session, procedure: string, opts?: KeepAdvertisedDirectOptions): () => void;
|
|
79
|
+
export type { CallOptions };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Direct-dial: caller-side resolve+one-hop-call and provider-side
|
|
2
|
+
// advertise-direct, built on macula-go's directdial package (see
|
|
3
|
+
// cabi/directdial.go's own doc for the trust model -- every candidate
|
|
4
|
+
// procedure_advertisement must carry a valid signature before its
|
|
5
|
+
// serving_station is trusted at all, the resolved station_endpoint must
|
|
6
|
+
// be signed by the station itself, and after the one-hop dial -- which
|
|
7
|
+
// trusts neither the TLS certificate nor nothing -- the freshly connected
|
|
8
|
+
// peer's own HELLO-proven identity is checked against the exact pubkey
|
|
9
|
+
// the signed DHT chain resolved, application-layer pinning instead of
|
|
10
|
+
// relying on the dial's own TLS -- and for why AdvertiseDirect publishes
|
|
11
|
+
// BOTH a plain ADVERTISE and a signed procedure_advertisement DHT record:
|
|
12
|
+
// skipping the plain ADVERTISE lets resolve+dial complete cleanly against
|
|
13
|
+
// a station with nothing registered to route the CALL to, a real bug
|
|
14
|
+
// macula-go fixed live 2026-08-30). The actual FFI plumbing lives on
|
|
15
|
+
// Session (session.ts's resolveDirect/callDirect/callDirectWithUcan/
|
|
16
|
+
// advertiseDirect), matching this SDK's own call()/serve() split; this
|
|
17
|
+
// file holds the shapes those share, plus keepAdvertisedDirect -- a
|
|
18
|
+
// standalone helper mirroring macula-go's own free-function
|
|
19
|
+
// KeepAdvertisedDirect, not a Session method (see its own doc for why).
|
|
20
|
+
/** How long keepAdvertisedDirect() waits between re-advertise ticks, in
|
|
21
|
+
* milliseconds, when opts.intervalMs is left unset. This is a real
|
|
22
|
+
* production margin against AdvertiseDirectOptions' own 48h default TTL
|
|
23
|
+
* actually expiring between ticks -- not chosen to match macula-go's own
|
|
24
|
+
* KeepAdvertisedDirect live-test interval (1s there, only to keep that
|
|
25
|
+
* particular test fast). A caller passing a much shorter `ttlMs` should
|
|
26
|
+
* pass a correspondingly shorter `intervalMs` too; this constant does not
|
|
27
|
+
* scale itself to `opts.ttlMs`. */
|
|
28
|
+
export const KEEP_ADVERTISED_DIRECT_INTERVAL_MS = 15 * 60 * 1000;
|
|
29
|
+
/** Re-advertises `procedure` as direct-dial-reachable on `session` (via
|
|
30
|
+
* `session.advertiseDirect()`) immediately, then again every
|
|
31
|
+
* `opts.intervalMs`, until the returned `stop()` is called -- macula-go's
|
|
32
|
+
* own `KeepAdvertisedDirect` free function, ported here as a standalone
|
|
33
|
+
* helper rather than a Session method for the identical reason
|
|
34
|
+
* macula-go's own is a free function taking a `*connection.Session`
|
|
35
|
+
* rather than a method on one: a station's registration for a procedure
|
|
36
|
+
* does not survive the connection that sent it being replaced, so a
|
|
37
|
+
* long-lived provider needs to call `AdvertiseDirect` again on its own
|
|
38
|
+
* schedule, and it is this function's CALLER's job to decide WHICH
|
|
39
|
+
* Session that runs on. See `Session.advertiseDirect()`'s own doc for why
|
|
40
|
+
* that must NOT be a Session with an active `serve()` on it
|
|
41
|
+
* (`advertiseDirect()`'s own `PutRecord` CALL would race `serve()`'s own
|
|
42
|
+
* reads of the same shared control stream): a long-lived provider that
|
|
43
|
+
* also serves `procedure` needs a SEPARATE Session (and identity -- this
|
|
44
|
+
* fleet enforces one connection per identity, kicking whichever connects
|
|
45
|
+
* second) for that, passed here instead of the serving Session.
|
|
46
|
+
*
|
|
47
|
+
* The returned `stop()` is synchronous -- unlike `Session.serve()`'s own
|
|
48
|
+
* async `stop()`, there is no pending tick to wait out and no unadvertise
|
|
49
|
+
* step: `advertiseDirect()`'s own DHT record simply expires on its own
|
|
50
|
+
* TTL once ticks stop, matching macula-go's own `KeepAdvertisedDirect`,
|
|
51
|
+
* which has no corresponding "undo" either. Calling `stop()` more than
|
|
52
|
+
* once is a no-op. */
|
|
53
|
+
export function keepAdvertisedDirect(session, procedure, opts = {}) {
|
|
54
|
+
const intervalMs = opts.intervalMs ?? KEEP_ADVERTISED_DIRECT_INTERVAL_MS;
|
|
55
|
+
let stopped = false;
|
|
56
|
+
const tick = () => {
|
|
57
|
+
session.advertiseDirect(procedure, { realm: opts.realm, ttlMs: opts.ttlMs }).catch((err) => {
|
|
58
|
+
opts.onError?.(err);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
tick();
|
|
62
|
+
const timer = setInterval(tick, intervalMs);
|
|
63
|
+
// Node keeps the event loop alive for a pending timer by default --
|
|
64
|
+
// unref() so a program that starts this loop with nothing else keeping
|
|
65
|
+
// it running (no active serve()/subscribe()/etc. elsewhere) can still
|
|
66
|
+
// exit on its own; a real, still-open Session doing other work keeps
|
|
67
|
+
// the process alive on its own merits regardless, unaffected by this.
|
|
68
|
+
timer.unref?.();
|
|
69
|
+
return () => {
|
|
70
|
+
if (stopped)
|
|
71
|
+
return;
|
|
72
|
+
stopped = true;
|
|
73
|
+
clearInterval(timer);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=directdial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directdial.js","sourceRoot":"","sources":["../src/directdial.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,iEAAiE;AACjE,sEAAsE;AACtE,kEAAkE;AAClE,wEAAwE;AACxE,uEAAuE;AACvE,0EAA0E;AAC1E,uEAAuE;AACvE,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAC1E,0EAA0E;AAC1E,qEAAqE;AACrE,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,oEAAoE;AACpE,4DAA4D;AAC5D,wEAAwE;AAmCxE;;;;;;;mCAOmC;AACnC,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAiBjE;;;;;;;;;;;;;;;;;;;;;;;sBAuBsB;AACtB,MAAM,UAAU,oBAAoB,CAAC,OAAgB,EAAE,SAAiB,EAAE,OAAoC,EAAE;IAC9G,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kCAAkC,CAAC;IACzE,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,OAAO,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YAClG,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,EAAE,CAAC;IACP,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC5C,oEAAoE;IACpE,uEAAuE;IACvE,sEAAsE;IACtE,qEAAqE;IACrE,sEAAsE;IACtE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAEhB,OAAO,GAAS,EAAE;QAChB,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,aAAa,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Handle } from "./binding.js";
|
|
2
|
+
export declare class Identity {
|
|
3
|
+
#private;
|
|
4
|
+
private constructor();
|
|
5
|
+
/** Mints a fresh identity, grinding an Ed25519 keypair until its
|
|
6
|
+
* NodeID's SHA-256 has the required S/Kademlia puzzle difficulty
|
|
7
|
+
* (macula-go's DefaultPuzzleDifficulty = 8 leading zero bits). This
|
|
8
|
+
* is real work done on the Go side -- not instant, not mocked. */
|
|
9
|
+
static generate(): Identity;
|
|
10
|
+
/** Reconstructs an identity from a previously-saved 32-byte Ed25519
|
|
11
|
+
* seed. Deterministic: does not re-grind the puzzle (a seed that
|
|
12
|
+
* already satisfied it at generation time still does). */
|
|
13
|
+
static fromSeedBytes(seed32: Uint8Array): Identity;
|
|
14
|
+
/** The 32-byte Ed25519 public key this identity is known by on the
|
|
15
|
+
* wire (CONNECT/HELLO's node_id field). */
|
|
16
|
+
get nodeId(): Uint8Array;
|
|
17
|
+
/** The 32-byte Ed25519 seed -- persist this (e.g. to a 0600 file)
|
|
18
|
+
* to reconstruct the identity later via fromSeedBytes. Treat as a
|
|
19
|
+
* private key: anyone with this seed can sign as this identity. */
|
|
20
|
+
get privateSeedBytes(): Uint8Array;
|
|
21
|
+
/** Signs data with this identity's private key (Ed25519, via
|
|
22
|
+
* macula-go's identity.KeyPair.Sign -- a direct ed25519.Sign wrapper)
|
|
23
|
+
* and returns the raw 64-byte signature. This is a generic signing
|
|
24
|
+
* primitive: no application-specific message format is baked in
|
|
25
|
+
* here or on the Go side -- data is signed exactly as given, byte
|
|
26
|
+
* for byte. A caller that needs a particular byte-layout convention
|
|
27
|
+
* (e.g. an ownership-proof format binding this signature to some
|
|
28
|
+
* other value) builds those bytes itself and passes the result in;
|
|
29
|
+
* that convention is the caller's concern, not this method's.
|
|
30
|
+
* Deterministic: signing the same data twice with the same identity
|
|
31
|
+
* produces the same signature (Ed25519 has no per-signature nonce
|
|
32
|
+
* randomness the way ECDSA does). */
|
|
33
|
+
sign(data: Uint8Array): Uint8Array;
|
|
34
|
+
/** Frees the Go-side handle. Safe to call more than once. */
|
|
35
|
+
dispose(): void;
|
|
36
|
+
/** The raw native handle, for Session.connect/close only -- they need
|
|
37
|
+
* it to establish/close a connection under this identity. JS private
|
|
38
|
+
* fields (#handle) are genuinely inaccessible from outside this
|
|
39
|
+
* class body, even to other code in this package, so this method is
|
|
40
|
+
* how Session and Identity cooperate across the FFI boundary. Not
|
|
41
|
+
* part of the intended public API. */
|
|
42
|
+
handleForFfi(): Handle;
|
|
43
|
+
}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Public identity API -- the one real capability this walking
|
|
2
|
+
// skeleton proves end-to-end: minting a Macula peer identity (an
|
|
3
|
+
// Ed25519 keypair, S/Kademlia puzzle-hardened) via macula-go's own
|
|
4
|
+
// identity.Generate(), reached through cabi/'s FFI boundary rather
|
|
5
|
+
// than reimplemented here.
|
|
6
|
+
//
|
|
7
|
+
// An Identity wraps a Go-side handle. It is a disposable, freeable
|
|
8
|
+
// resource: call dispose() when done with it (or let the process
|
|
9
|
+
// exit -- the Go side doesn't leak across a process lifetime, but a
|
|
10
|
+
// long-running host process minting many identities should dispose
|
|
11
|
+
// each one). There is no finalizer/GC integration in this skeleton;
|
|
12
|
+
// forgetting to call dispose() leaks the Go-side handle for the life
|
|
13
|
+
// of the process, exactly as macula-php's identical handle-based
|
|
14
|
+
// design does.
|
|
15
|
+
import { native } from "./binding.js";
|
|
16
|
+
export class Identity {
|
|
17
|
+
#handle;
|
|
18
|
+
constructor(handle) {
|
|
19
|
+
this.#handle = handle;
|
|
20
|
+
}
|
|
21
|
+
/** Mints a fresh identity, grinding an Ed25519 keypair until its
|
|
22
|
+
* NodeID's SHA-256 has the required S/Kademlia puzzle difficulty
|
|
23
|
+
* (macula-go's DefaultPuzzleDifficulty = 8 leading zero bits). This
|
|
24
|
+
* is real work done on the Go side -- not instant, not mocked. */
|
|
25
|
+
static generate() {
|
|
26
|
+
return new Identity(native.identityGenerate());
|
|
27
|
+
}
|
|
28
|
+
/** Reconstructs an identity from a previously-saved 32-byte Ed25519
|
|
29
|
+
* seed. Deterministic: does not re-grind the puzzle (a seed that
|
|
30
|
+
* already satisfied it at generation time still does). */
|
|
31
|
+
static fromSeedBytes(seed32) {
|
|
32
|
+
return new Identity(native.identityFromSeedBytes(seed32));
|
|
33
|
+
}
|
|
34
|
+
#requireHandle() {
|
|
35
|
+
if (this.#handle === null) {
|
|
36
|
+
throw new Error("macula-ts: Identity used after dispose()");
|
|
37
|
+
}
|
|
38
|
+
return this.#handle;
|
|
39
|
+
}
|
|
40
|
+
/** The 32-byte Ed25519 public key this identity is known by on the
|
|
41
|
+
* wire (CONNECT/HELLO's node_id field). */
|
|
42
|
+
get nodeId() {
|
|
43
|
+
return native.identityNodeId(this.#requireHandle());
|
|
44
|
+
}
|
|
45
|
+
/** The 32-byte Ed25519 seed -- persist this (e.g. to a 0600 file)
|
|
46
|
+
* to reconstruct the identity later via fromSeedBytes. Treat as a
|
|
47
|
+
* private key: anyone with this seed can sign as this identity. */
|
|
48
|
+
get privateSeedBytes() {
|
|
49
|
+
return native.identityPrivateBytes(this.#requireHandle());
|
|
50
|
+
}
|
|
51
|
+
/** Signs data with this identity's private key (Ed25519, via
|
|
52
|
+
* macula-go's identity.KeyPair.Sign -- a direct ed25519.Sign wrapper)
|
|
53
|
+
* and returns the raw 64-byte signature. This is a generic signing
|
|
54
|
+
* primitive: no application-specific message format is baked in
|
|
55
|
+
* here or on the Go side -- data is signed exactly as given, byte
|
|
56
|
+
* for byte. A caller that needs a particular byte-layout convention
|
|
57
|
+
* (e.g. an ownership-proof format binding this signature to some
|
|
58
|
+
* other value) builds those bytes itself and passes the result in;
|
|
59
|
+
* that convention is the caller's concern, not this method's.
|
|
60
|
+
* Deterministic: signing the same data twice with the same identity
|
|
61
|
+
* produces the same signature (Ed25519 has no per-signature nonce
|
|
62
|
+
* randomness the way ECDSA does). */
|
|
63
|
+
sign(data) {
|
|
64
|
+
return native.identitySign(this.#requireHandle(), data);
|
|
65
|
+
}
|
|
66
|
+
/** Frees the Go-side handle. Safe to call more than once. */
|
|
67
|
+
dispose() {
|
|
68
|
+
if (this.#handle !== null) {
|
|
69
|
+
native.identityFree(this.#handle);
|
|
70
|
+
this.#handle = null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** The raw native handle, for Session.connect/close only -- they need
|
|
74
|
+
* it to establish/close a connection under this identity. JS private
|
|
75
|
+
* fields (#handle) are genuinely inaccessible from outside this
|
|
76
|
+
* class body, even to other code in this package, so this method is
|
|
77
|
+
* how Session and Identity cooperate across the FFI boundary. Not
|
|
78
|
+
* part of the intended public API. */
|
|
79
|
+
handleForFfi() {
|
|
80
|
+
return this.#requireHandle();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,iEAAiE;AACjE,mEAAmE;AACnE,mEAAmE;AACnE,2BAA2B;AAC3B,EAAE;AACF,mEAAmE;AACnE,iEAAiE;AACjE,oEAAoE;AACpE,mEAAmE;AACnE,oEAAoE;AACpE,qEAAqE;AACrE,iEAAiE;AACjE,eAAe;AACf,OAAO,EAAE,MAAM,EAAe,MAAM,cAAc,CAAC;AAEnD,MAAM,OAAO,QAAQ;IACnB,OAAO,CAAgB;IAEvB,YAAoB,MAAc;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED;;;sEAGkE;IAClE,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;8DAE0D;IAC1D,MAAM,CAAC,aAAa,CAAC,MAAkB;QACrC,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;+CAC2C;IAC3C,IAAI,MAAM;QACR,OAAO,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IACtD,CAAC;IAED;;uEAEmE;IACnE,IAAI,gBAAgB;QAClB,OAAO,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;;;;;;;yCAWqC;IACrC,IAAI,CAAC,IAAgB;QACnB,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,6DAA6D;IAC7D,OAAO;QACL,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;;;;0CAKsC;IACtC,YAAY;QACV,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;IAC/B,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Identity } from "./identity.js";
|
|
2
|
+
export { Session, type CallOptions } from "./session.js";
|
|
3
|
+
export { MaculaCallError, type JsonValue, type Bolt4ErrorInfo } from "./rpc.js";
|
|
4
|
+
export { DhtRecordType, DHT_DEFAULT_TTL_MS, type DhtRecord } from "./dht.js";
|
|
5
|
+
export type { PublishOptions, PubsubEvent } from "./pubsub.js";
|
|
6
|
+
export { ContentNotFoundError } from "./content.js";
|
|
7
|
+
export { Ucan, type UcanCapability, type UcanFactValue, type UcanMintOptions } from "./ucan.js";
|
|
8
|
+
export { keepAdvertisedDirect, KEEP_ADVERTISED_DIRECT_INTERVAL_MS, type DirectDialTarget, type AdvertiseDirectOptions, type KeepAdvertisedDirectOptions, } from "./directdial.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Identity } from "./identity.js";
|
|
2
|
+
export { Session } from "./session.js";
|
|
3
|
+
export { MaculaCallError } from "./rpc.js";
|
|
4
|
+
export { DhtRecordType, DHT_DEFAULT_TTL_MS } from "./dht.js";
|
|
5
|
+
export { ContentNotFoundError } from "./content.js";
|
|
6
|
+
export { Ucan } from "./ucan.js";
|
|
7
|
+
export { keepAdvertisedDirect, KEEP_ADVERTISED_DIRECT_INTERVAL_MS, } from "./directdial.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,eAAe,EAAuC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAkB,MAAM,UAAU,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,IAAI,EAAiE,MAAM,WAAW,CAAC;AAChG,OAAO,EACL,oBAAoB,EACpB,kCAAkC,GAInC,MAAM,iBAAiB,CAAC"}
|