@reticulum/dacar 1.2.2 → 1.4.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 CHANGED
@@ -19,9 +19,9 @@ This is a modern ES-module package with JSDoc type annotations that runs on
19
19
  | HMAC-SHA256 / SHA-256 (§3.3, §6.1) | Web Crypto `crypto.subtle` | Standard, runtime-portable |
20
20
  | MessagePack (§5.3) | `@reticulum/core` `MsgPack` | Reuses the canonical stack's encoder |
21
21
 
22
- `@reticulum/core` is the only dependency (for both the core and the optional
23
- transport adapters — which additionally use its `Destination`, `Link`,
24
- `LXMRouter`, and `RFedClient`).
22
+ `@reticulum/core` is the base dependency of the pure core; the optional
23
+ transport adapters additionally use `@reticulum/lxmf` (the `LXMRouter`),
24
+ `@reticulum/rfed` (the `RFedClient`), and core's `Destination`/`Link`.
25
25
 
26
26
  > **Note on MessagePack + 64-bit HLCs:** a packed HLC (`physical_ms << 16`)
27
27
  > exceeds `Number.MAX_SAFE_INTEGER`, so it is represented as a `bigint`. The HLC
@@ -112,8 +112,9 @@ console.log(await engine.evaluate("sensor:wind", "read", ROOT)); // true
112
112
 
113
113
  The pure core has no transport: it is wired to the Reticulum transports by the
114
114
  optional `@reticulum/dacar/transport` subpath. Importing the core
115
- (`@reticulum/dacar`) never pulls it in, and every adapter depends only on
116
- `@reticulum/core` (already a core dependency), so it adds **no new dependency**.
115
+ (`@reticulum/dacar`) never pulls it in. The transport adapters build on
116
+ `@reticulum/core`, `@reticulum/lxmf`, and `@reticulum/rfed` (since reticulum-js
117
+ 0.8.2, LXMF and rfed are packages of their own rather than core subpaths).
117
118
 
118
119
  Every transport funnels received bytes through the same verify-on-ingest seam
119
120
  (`DeltaReceiver.applyPayload()`, §11.2.4): a Delta is decoded, authenticated by
@@ -159,7 +160,7 @@ import {
159
160
  ### RFed convergence
160
161
 
161
162
  ```js
162
- import { RFedClient } from "@reticulum/core";
163
+ import { RFedClient } from "@reticulum/rfed";
163
164
  import { DeltaReceiver, StateVector } from "@reticulum/dacar";
164
165
  import { RfedDeltaSync } from "@reticulum/dacar/transport";
165
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reticulum/dacar",
3
- "version": "1.2.2",
3
+ "version": "1.4.0",
4
4
  "description": "JavaScript implementation of Dacar, a Decentralized Access Control system for Reticulum",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -44,8 +44,10 @@
44
44
  "node": ">=20"
45
45
  },
46
46
  "dependencies": {
47
- "@reticulum/core": "^0.6.5",
48
- "@reticulum/node": "^0.6.5",
47
+ "@reticulum/core": "^0.8.2",
48
+ "@reticulum/lxmf": "^0.8.2",
49
+ "@reticulum/node": "^0.8.2",
50
+ "@reticulum/rfed": "^0.8.2",
49
51
  "@types/node": "^26.2.0"
50
52
  },
51
53
  "publishConfig": {
package/src/cli/dacar.js CHANGED
@@ -35,7 +35,7 @@ import process from "node:process";
35
35
  import { Identity, toHex } from "@reticulum/core";
36
36
  import { MemoryStorageAdapter } from "@reticulum/core";
37
37
  import { DacarFileAdapter } from "./fileStore.js";
38
- import { RFedClient } from "@reticulum/core/src/rfed/index.js";
38
+ import { RFedClient } from "@reticulum/rfed";
39
39
  import { bootRns } from "./rns_boot.js";
40
40
 
41
41
  import { Action, Operation, Tuple, Engine } from "../index.js";
package/src/index.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * (§4.1), and the state is bounded by Time-Horizon Tombstone Pruning (§9).
10
10
  */
11
11
 
12
- export const __version__ = "1.0.0";
12
+ export const __version__ = "1.4.0";
13
13
  export const __specVersion__ = "1.0-RC7";
14
14
 
15
15
  // HLC (§5.1)
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * These wire the pure, transport-agnostic core — the §8 `Challenge`/
5
5
  * `AuthoritativeServer`/`ChallengeClient` and the §11 `DeltaReceiver` — to the
6
- * concrete Reticulum transports from `@reticulum/core`:
6
+ * concrete Reticulum transports from `@reticulum/core`, `@reticulum/lxmf`, and
7
+ * `@reticulum/rfed` (since reticulum-js 0.8.2, LXMF and rfed are packages of
8
+ * their own rather than core subpaths):
7
9
  *
8
10
  * - {@link RnsIdentityResolver} §3.1, §11.2.4 recall → verify key
9
11
  * - {@link RnsChallengeServer} &c. §8 Challenge over an RNS Link
@@ -11,9 +13,8 @@
11
13
  * - {@link RfedDeltaSync} §11.1 RFed many-to-many convergence
12
14
  *
13
15
  * Importing the pure core (`@reticulum/dacar`) does **not** import this
14
- * subpath: it is opt-in via `@reticulum/dacar/transport`. Every adapter depends
15
- * only on `@reticulum/core`, which the core already depends on, so the
16
- * transport layer adds no new dependency.
16
+ * subpath: it is opt-in via `@reticulum/dacar/transport`. The adapters build
17
+ * on the `@reticulum/*` reticulum-js packages (core, lxmf, rfed).
17
18
  */
18
19
 
19
20
  export { RnsIdentityResolver } from "./rnsIdentity.js";
@@ -15,10 +15,10 @@
15
15
  * through the router.
16
16
  *
17
17
  * This module is part of the optional transport layer: importing the pure core
18
- * never pulls it in. It depends only on `@reticulum/core`, which the core
19
- * already depends on, so no new dependency is added.
18
+ * never pulls it in. It depends on `@reticulum/lxmf` (which itself builds on
19
+ * `@reticulum/core`).
20
20
  *
21
- * Typical use (receiver, wired to a {@link import("@reticulum/core/src/lxmf/index.js").LXMRouter
21
+ * Typical use (receiver, wired to a {@link import("@reticulum/lxmf").LXMRouter
22
22
  * LXMRouter}):
23
23
  *
24
24
  * ```js
@@ -38,7 +38,7 @@
38
38
  * await delivery.handleMessage(event.detail.message);
39
39
  */
40
40
 
41
- import { LXMessage as LXMFMessage } from "@reticulum/core/src/lxmf/index.js";
41
+ import { LXMessage as LXMFMessage } from "@reticulum/lxmf";
42
42
  import { LXMF_DELIVERY_TITLE } from "../naming.js";
43
43
 
44
44
  /**
@@ -60,7 +60,7 @@ export function messageTitle(message) {
60
60
  /**
61
61
  * Best-effort content of an LXMF message as raw bytes (the §5.3 Delta payload).
62
62
  *
63
- * `@reticulum/core`'s `Message.deserialize()` UTF-8-decodes the content element
63
+ * `@reticulum/lxmf`'s `Message.deserialize()` UTF-8-decodes the content element
64
64
  * into `message.content`, which corrupts arbitrary binary Deltas. The raw bytes
65
65
  * are preserved on `_decodedPayload[2]` (the same field the library uses
66
66
  * internally for §5.6 signature re-verification), so this helper recovers the
@@ -99,13 +99,13 @@ export class LxmfDeltaDelivery {
99
99
  * @param {import("../delta.js").DeltaReceiver | null} [opts.receiver]
100
100
  * The shared DeltaReceiver (state + key resolver). May be omitted on a
101
101
  * send-only node (then `handleMessage` throws if called).
102
- * @param {import("@reticulum/core/src/lxmf/index.js").LXMRouter | null} [opts.router]
102
+ * @param {import("@reticulum/lxmf").LXMRouter | null} [opts.router]
103
103
  * Optional bound `LXMRouter` for `deliver` / `ingestPaperUri`.
104
104
  */
105
105
  constructor({ receiver = null, router = null } = {}) {
106
106
  /** @type {import("../delta.js").DeltaReceiver | null} */
107
107
  this._receiver = receiver;
108
- /** @type {import("@reticulum/core/src/lxmf/index.js").LXMRouter | null} */
108
+ /** @type {import("@reticulum/lxmf").LXMRouter | null} */
109
109
  this._router = router;
110
110
  }
111
111
 
@@ -121,7 +121,7 @@ export class LxmfDeltaDelivery {
121
121
  * @param {Uint8Array} deltaPayload
122
122
  * @param {Uint8Array} destinationHash The recipient `lxmf.delivery` hash.
123
123
  * @param {Uint8Array} sourceHash The sender's `lxmf.delivery` hash.
124
- * @returns {import("@reticulum/core/src/lxmf/index.js").LXMessage}
124
+ * @returns {import("@reticulum/lxmf").LXMessage}
125
125
  */
126
126
  makeMessage(deltaPayload, destinationHash, sourceHash) {
127
127
  if (!(deltaPayload instanceof Uint8Array)) {
@@ -145,7 +145,7 @@ export class LxmfDeltaDelivery {
145
145
  * @param {Uint8Array} destinationHash The recipient `lxmf.delivery` hash.
146
146
  * @param {Object} [opts]
147
147
  * @param {Uint8Array | null} [opts.linkId] Reuse an existing DIRECT link id.
148
- * @returns {Promise<import("@reticulum/core/src/lxmf/index.js").LXMessage>}
148
+ * @returns {Promise<import("@reticulum/lxmf").LXMessage>}
149
149
  */
150
150
  async deliver(deltaPayload, destinationHash, { linkId = null } = {}) {
151
151
  if (!this._router) {
@@ -210,7 +210,7 @@ export class LxmfDeltaDelivery {
210
210
  * ingest result (the reconstructed message, or `null` if it was not for this
211
211
  * node / already ingested).
212
212
  * @param {string} uri
213
- * @returns {Promise<import("@reticulum/core/src/lxmf/index.js").LXMessage | null>}
213
+ * @returns {Promise<import("@reticulum/lxmf").LXMessage | null>}
214
214
  */
215
215
  async ingestPaperUri(uri) {
216
216
  if (!this._router) {
@@ -10,7 +10,7 @@
10
10
  * delivery — **never** through the unauthenticated `StateVector.merge()` path.
11
11
  * A forged or stale Delta is simply dropped before it can mutate state.
12
12
  *
13
- * `RfedDeltaSync` wraps a `@reticulum/core` `RFedClient`. A Delta travels in
13
+ * `RfedDeltaSync` wraps a `@reticulum/rfed` `RFedClient`. A Delta travels in
14
14
  * Dacar's **compact inner format** (§11.1.1): the raw §5.3 payload is placed
15
15
  * straight after the RTID source-identity prelude and EC-encrypted to the
16
16
  * derived channel identity — no LXMF envelope, which would only duplicate the
@@ -19,7 +19,7 @@
19
19
  * discriminator (every message on it is a Dacar Delta), and the recovered Delta
20
20
  * bytes are fed to `DeltaReceiver`.
21
21
  *
22
- * The compact format is built on `@reticulum/core`'s raw RFed primitives —
22
+ * The compact format is built on `@reticulum/rfed`'s raw RFed primitives —
23
23
  * `subscribeRaw` / `publishRaw` / `unwrapRawChannelMessage` — which carry an
24
24
  * arbitrary self-authenticating payload in place of the LXMF tail. The Delta's
25
25
  * own Ed25519 signature (§5.3 field [7]) is the authenticity check at
@@ -31,8 +31,8 @@
31
31
  * channel uses the compact format.
32
32
  *
33
33
  * This module is part of the optional transport layer: importing the pure core
34
- * never pulls it in. It depends only on `@reticulum/core`, which the core
35
- * already depends on, so no new dependency is added. It mirrors
34
+ * never pulls it in. It depends on `@reticulum/rfed` (which itself builds on
35
+ * `@reticulum/core`). It mirrors
36
36
  * `python/dacar/transport/rfed_sync.py` (the canonical implementation).
37
37
  *
38
38
  * Typical use:
@@ -46,17 +46,16 @@
46
46
  * ```
47
47
  */
48
48
 
49
- import { Destination } from "@reticulum/core/src/core/destination.js";
49
+ import { Destination, MsgPack } from "@reticulum/core";
50
50
  import {
51
51
  deriveChannel,
52
52
  unwrapRawChannelMessage,
53
- } from "@reticulum/core/src/rfed/index.js";
54
- import { MicroMsgPack } from "@reticulum/core/src/utils/msgpack.js";
53
+ } from "@reticulum/rfed";
55
54
  import { RFED_TOPIC } from "../naming.js";
56
55
 
57
56
  /**
58
57
  * The minimal `RFedClient` surface this adapter relies on. The real client from
59
- * `@reticulum/core` satisfies it; tests inject a fake. The raw-publish API
58
+ * `@reticulum/rfed` satisfies it; tests inject a fake. The raw-publish API
60
59
  * (`subscribeRaw` / `publishRaw`) carries a self-authenticating payload in the
61
60
  * RTID prelude instead of an LXMF envelope (§11.1.1).
62
61
  *
@@ -82,7 +81,7 @@ import { RFED_TOPIC } from "../naming.js";
82
81
  * @typedef {Object} RfedDecodedRaw
83
82
  * @property {"raw"|"lxmf"} kind
84
83
  * @property {Uint8Array} [payload] Raw application payload (`kind === "raw"`).
85
- * @property {import("@reticulum/core/src/core/identity.js").Identity} [senderIdentity]
84
+ * @property {import("@reticulum/core").Identity} [senderIdentity]
86
85
  * @property {Uint8Array} [senderPub]
87
86
  * @property {Uint8Array} [channelHash]
88
87
  * @property {string} [channelName]
@@ -100,7 +99,7 @@ export class RfedDeltaSync {
100
99
  * @param {import("../delta.js").DeltaReceiver | null} [opts.receiver]
101
100
  * The shared DeltaReceiver (state + key resolver). May be omitted on a
102
101
  * publish-only node (then `listen`/`pull` throw if called).
103
- * @param {RFedClientLike} opts.client A `@reticulum/core` `RFedClient`.
102
+ * @param {RFedClientLike} opts.client A `@reticulum/rfed` `RFedClient`.
104
103
  * @param {string} [opts.topic] RFed channel name (default `dacar.policy.v1`).
105
104
  */
106
105
  constructor({ receiver = null, client, topic = RFED_TOPIC }) {
@@ -191,7 +190,7 @@ export class RfedDeltaSync {
191
190
  // needing an announce. Best-effort: decode must still succeed without it.
192
191
  try {
193
192
  // Extract issuer_hash (field [0]) from the delta to map identity.
194
- const decodedDelta = MicroMsgPack.decode(decoded.payload);
193
+ const decodedDelta = MsgPack.decode(decoded.payload);
195
194
  if (Array.isArray(decodedDelta) && decodedDelta.length > 0) {
196
195
  const issuerHash = decodedDelta[0];
197
196
  if (issuerHash instanceof Uint8Array && issuerHash.length === 16) {
@@ -252,7 +251,7 @@ export class RfedDeltaSync {
252
251
  // needing an announce. Best-effort: decode must still succeed without it.
253
252
  try {
254
253
  // Extract issuer_hash (field [0]) from the delta to map identity.
255
- const decodedDelta = MicroMsgPack.decode(decoded.payload);
254
+ const decodedDelta = MsgPack.decode(decoded.payload);
256
255
  if (Array.isArray(decodedDelta) && decodedDelta.length > 0) {
257
256
  const issuerHash = decodedDelta[0];
258
257
  if (issuerHash instanceof Uint8Array && issuerHash.length === 16) {
@@ -21,9 +21,8 @@
21
21
  * identities always win.
22
22
  *
23
23
  * This module is part of the optional transport layer: importing the pure
24
- * core (`@reticulum/dacar`) never pulls it in. It depends only on
25
- * `@reticulum/core`'s `Destination.recall`, which the core already depends on
26
- * for `Identity` / `MsgPack`, so it adds no new dependency.
24
+ * core (`@reticulum/dacar`) never pulls it in. It uses only `@reticulum/core`'s
25
+ * `Destination.recall`.
27
26
  */
28
27
 
29
28
  import { Destination } from "@reticulum/core";