@de./sdk 2.1.1 → 2.2.1

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.
@@ -1,24 +1,21 @@
1
1
  import type { OrderTrackingEvent } from '@de./types';
2
2
  import type { RTLocation, Message, Peer } from '../../types';
3
- import type { AccessOptions } from '../../types/access';
4
- import AccessManager from '../Access';
3
+ import RealtimeSocket, { type RealtimeConnectOptions } from '../realtime-socket';
5
4
  export type AgentRealtimeContext = {
6
5
  wid: string;
7
6
  type: string;
8
7
  xcode: string;
9
8
  };
10
- export default class AgentRealtime extends AccessManager {
11
- private nsp?;
12
- private iosHost;
9
+ export default class AgentRealtime extends RealtimeSocket {
13
10
  private agentId?;
14
- constructor(access: AccessOptions);
15
- connect(agentId: string): Promise<void>;
16
- disconnect(): boolean;
11
+ protected get utype(): string;
17
12
  /**
18
- * Join an order tracking room with a Join Room Token issued by
19
- * GET /v1/tracking/:reference (role must match this socket's utype)
13
+ * @param options `getToken` supplies a fresh access token per attempt. A
14
+ * rider's phone reconnects constantly and De.'s tokens are
15
+ * short-lived, so without it the socket comes back refused —
16
+ * or, worse, comes back connected and in none of its rooms.
20
17
  */
21
- join(jrtoken: string): Promise<boolean>;
18
+ connect(agentId: string, options?: RealtimeConnectOptions): Promise<void>;
22
19
  sendLocation(location: RTLocation): this;
23
20
  sendMessage(message: Message): this;
24
21
  onOrderUpdate(fn: (event: OrderTrackingEvent) => void): this;
@@ -3,50 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const socket_io_client_1 = __importDefault(require("socket.io-client"));
7
- const Access_1 = __importDefault(require("../Access"));
8
- const baseUrl_1 = require("../../baseUrl");
9
- class AgentRealtime extends Access_1.default {
10
- constructor(access) {
11
- var _a;
12
- super(access, 'API');
13
- // Socket.io is served by the same de.arch API server, so an explicit
14
- // origin governs the socket exactly as it governs the requests — without
15
- // this, a client pointed at a self-hosted De. still opened its socket
16
- // against the environment table's host.
17
- this.iosHost = ((_a = access.baseUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/+$/, ''))
18
- || (0, baseUrl_1.baseURL)('API', access.env || 'dev', access.devHostname);
19
- }
20
- connect(agentId) {
21
- return new Promise((resolve, reject) => {
22
- const auth = {
23
- utype: 'agent',
24
- id: agentId,
25
- remoteOrigin: this.remoteOrigin,
26
- accessToken: this.accessToken
27
- };
28
- this.agentId = agentId;
29
- this.nsp = (0, socket_io_client_1.default)(this.iosHost, { auth });
30
- this.nsp.on('connect', resolve);
31
- this.nsp.on('connect_error', reject);
32
- });
33
- }
34
- disconnect() {
35
- var _a;
36
- (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.disconnect();
37
- return true;
38
- }
6
+ const realtime_socket_1 = __importDefault(require("../realtime-socket"));
7
+ class AgentRealtime extends realtime_socket_1.default {
8
+ get utype() { return 'agent'; }
39
9
  /**
40
- * Join an order tracking room with a Join Room Token issued by
41
- * GET /v1/tracking/:reference (role must match this socket's utype)
10
+ * @param options `getToken` supplies a fresh access token per attempt. A
11
+ * rider's phone reconnects constantly and De.'s tokens are
12
+ * short-lived, so without it the socket comes back refused —
13
+ * or, worse, comes back connected and in none of its rooms.
42
14
  */
43
- join(jrtoken) {
44
- return new Promise((resolve, reject) => {
45
- var _a;
46
- (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('JOIN', jrtoken, (errmess) => {
47
- errmess ? reject(new Error(errmess)) : resolve(true);
48
- });
49
- });
15
+ connect(agentId, options) {
16
+ this.agentId = agentId;
17
+ return this.open(agentId, options);
50
18
  }
51
19
  // ── Order room streams (after join) ─────────────────────────────────────
52
20
  sendLocation(location) {
@@ -1 +1 @@
1
- {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../../src/allend/Agent/realtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../../src/allend/Agent/realtime.ts"],"names":[],"mappings":";;;;;AAGA,yEAAgF;AA2BhF,MAAqB,aAAc,SAAQ,yBAAc;IAGvD,IAAc,KAAK,KAAa,OAAO,OAAO,CAAA,CAAC,CAAC;IAEhD;;;;;OAKG;IACH,OAAO,CAAE,OAAe,EAAE,OAAgC;QACxD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,OAAO,IAAI,CAAC,IAAI,CAAE,OAAO,EAAE,OAAO,CAAE,CAAA;IACtC,CAAC;IAED,2EAA2E;IAE3E,YAAY,CAAE,QAAoB;;QAChC,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAE,CAAA;QAC5C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CAAE,OAAgB;;QAC3B,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAE,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,aAAa,CAAE,EAAyC;;QACtD,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,SAAS,CAAE,EAAgC;;QACzC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAE,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CAAE,EAA0B;;QACrC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAE,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,cAAc,CAAE,EAA0B;;QACxC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,2EAA2E;IAE3E,gBAAgB,CAAE,OAA6B,EAAE,OAAe;;QAC9D,IAAI,CAAC,IAAI,CAAC,OAAO;YAAG,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;QACpD,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAE,CAAA;QACjF,OAAO,IAAI,CAAA;IACb,CAAC;IAED,iBAAiB,CAAE,OAA6B,EAAE,OAAe,EAAE,UAAmB;;QACpF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAG,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;QACpD,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAE,CAAA;QAC9F,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAE,OAA6B,EAAE,QAAoB,EAAE,MAAe;;QAClF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAG,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAA;QACpD,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAE,CAAA;QAC/F,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAxED,gCAwEC"}
@@ -1,13 +1,40 @@
1
- import type { Peer } from '../../types';
2
- import type { AccessOptions } from '../../types/access';
3
- import AccessManager from '../Access';
4
- export default class Realtime extends AccessManager {
5
- private nsp?;
6
- private iosHost;
7
- constructor(access: AccessOptions);
8
- connect(clientId: string): Promise<void>;
9
- disconnect(): boolean;
10
- join(jrtoken: string): Promise<boolean>;
1
+ import type { OrderTrackingEvent } from '@de./types';
2
+ import type { RTLocation, Message, Peer } from '../../types';
3
+ import RealtimeSocket, { type RealtimeConnectOptions } from '../realtime-socket';
4
+ /**
5
+ * Who this connection is, in De.'s vocabulary.
6
+ *
7
+ * A client is the party that engaged the provider — a CSP, a merchant, a
8
+ * branch. A customer is the person the delivery is handed to. They are not
9
+ * the same party and De. does not put them in the same room, so a customer
10
+ * app connecting as 'client' hears nothing addressed to customers and cannot
11
+ * redeem a customer's tracking token.
12
+ */
13
+ export type RealtimeUserType = 'client' | 'customer' | 'vendor';
14
+ export default class Realtime extends RealtimeSocket {
15
+ private as;
16
+ protected get utype(): string;
17
+ /**
18
+ * @param id The uid the tracking session was issued for.
19
+ * @param utype Must equal the `role` that session was issued with.
20
+ * @param options `getToken` supplies a fresh access token per attempt —
21
+ * without it a reconnect after the token's short life is
22
+ * refused, and the app is left with an open socket that
23
+ * delivers nothing.
24
+ */
25
+ connect(id: string, utype?: RealtimeUserType, options?: RealtimeConnectOptions): Promise<void>;
26
+ /**
27
+ * The rider's position, as it moves.
28
+ *
29
+ * Rate-limited by De. to 10 per second per sender, so this is a stream and
30
+ * not a trickle: render from it directly rather than re-fetching anything.
31
+ */
32
+ onLocation(fn: (location: RTLocation) => void): this;
33
+ onRoute(fn: (route: any) => void): this;
34
+ onOrderUpdate(fn: (event: OrderTrackingEvent) => void): this;
35
+ onMessage(fn: (message: Message) => void): this;
36
+ sendMessage(message: Message): this;
37
+ onJoined(fn: (peer: Peer) => void): this;
11
38
  onLeft(fn: (peer: Peer) => void): this;
12
39
  onConnected(fn: (peer: Peer) => void): this;
13
40
  onDisconnected(fn: (peer: Peer) => void): this;
@@ -3,44 +3,62 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const socket_io_client_1 = __importDefault(require("socket.io-client"));
7
- const Access_1 = __importDefault(require("../Access"));
8
- const baseUrl_1 = require("../../baseUrl");
9
- class Realtime extends Access_1.default {
10
- constructor(access) {
11
- var _a;
12
- super(access, 'API');
13
- // Socket server host
14
- // An explicit origin governs the socket as it governs the requests.
15
- this.iosHost = ((_a = access.baseUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/+$/, ''))
16
- || (0, baseUrl_1.baseURL)('RTS', access.env, access.devHostname);
17
- }
18
- connect(clientId) {
19
- return new Promise((resolve, reject) => {
20
- // Connect to main clients namespace
21
- const auth = {
22
- utype: 'client',
23
- id: clientId,
24
- remoteOrigin: (globalThis === null || globalThis === void 0 ? void 0 : globalThis.window) ? globalThis.origin : this.remoteOrigin,
25
- accessToken: this.accessToken
26
- };
27
- this.nsp = (0, socket_io_client_1.default)(this.iosHost, { auth });
28
- this.nsp.on('connect', resolve);
29
- this.nsp.on('connect_error', reject);
30
- });
31
- }
32
- disconnect() {
33
- var _a;
34
- (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.disconnect();
35
- return true;
36
- }
37
- join(jrtoken) {
38
- return new Promise((resolve, reject) => {
39
- var _a;
40
- (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('JOIN', jrtoken, (errmess) => {
41
- errmess ? reject(new Error(errmess)) : resolve(true);
42
- });
43
- });
6
+ const realtime_socket_1 = __importDefault(require("../realtime-socket"));
7
+ class Realtime extends realtime_socket_1.default {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.as = 'client';
11
+ }
12
+ get utype() { return this.as; }
13
+ /**
14
+ * @param id The uid the tracking session was issued for.
15
+ * @param utype Must equal the `role` that session was issued with.
16
+ * @param options `getToken` supplies a fresh access token per attempt —
17
+ * without it a reconnect after the token's short life is
18
+ * refused, and the app is left with an open socket that
19
+ * delivers nothing.
20
+ */
21
+ connect(id, utype = 'client', options) {
22
+ this.as = utype;
23
+ return this.open(id, options);
24
+ }
25
+ // ── Order room streams (after join) ─────────────────────────────────────
26
+ /**
27
+ * The rider's position, as it moves.
28
+ *
29
+ * Rate-limited by De. to 10 per second per sender, so this is a stream and
30
+ * not a trickle: render from it directly rather than re-fetching anything.
31
+ */
32
+ onLocation(fn) {
33
+ var _a;
34
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.on('LOCATION-CHANGE', fn);
35
+ return this;
36
+ }
37
+ onRoute(fn) {
38
+ var _a;
39
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.on('ROUTE-CHANGE', fn);
40
+ return this;
41
+ }
42
+ onOrderUpdate(fn) {
43
+ var _a;
44
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.on('ORDER_UPDATE', fn);
45
+ return this;
46
+ }
47
+ onMessage(fn) {
48
+ var _a;
49
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.on('MESSAGE', fn);
50
+ return this;
51
+ }
52
+ sendMessage(message) {
53
+ var _a;
54
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('MESSAGE', message);
55
+ return this;
56
+ }
57
+ // ── Presence ────────────────────────────────────────────────────────────
58
+ onJoined(fn) {
59
+ var _a;
60
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.on('JOINED', fn);
61
+ return this;
44
62
  }
45
63
  onLeft(fn) {
46
64
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/allend/Realtime/index.ts"],"names":[],"mappings":";;;;;AAIA,wEAA6C;AAC7C,uDAAqC;AACrC,2CAAuC;AAEvC,MAAqB,QAAS,SAAQ,gBAAa;IAIjD,YAAa,MAAqB;;QAChC,KAAK,CAAE,MAAM,EAAE,KAAK,CAAE,CAAA;QACtB,qBAAqB;QACrB,oEAAoE;QACpE,IAAI,CAAC,OAAO,GAAG,CAAA,MAAA,MAAM,CAAC,OAAO,0CAAE,OAAO,CAAE,MAAM,EAAE,EAAE,CAAE;eACjC,IAAA,iBAAO,EAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAE,CAAA;IACpE,CAAC;IAED,OAAO,CAAE,QAAgB;QACvB,OAAO,IAAI,OAAO,CAAE,CAAE,OAAO,EAAE,MAAM,EAAG,EAAE;YACxC,oCAAoC;YACpC,MAAM,IAAI,GAA0B;gBAClC,KAAK,EAAE,QAAQ;gBACf,EAAE,EAAE,QAAQ;gBACZ,YAAY,EAAE,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,EAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAsB;gBAClF,WAAW,EAAE,IAAI,CAAC,WAAqB;aACxC,CAAA;YAED,IAAI,CAAC,GAAG,GAAG,IAAA,0BAAE,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAE,CAAA;YACvC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAE,CAAA;YAChC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,CAAE,CAAA;QACvC,CAAC,CAAE,CAAA;IACL,CAAC;IACD,UAAU;;QACR,MAAA,IAAI,CAAC,GAAG,0CAAE,UAAU,EAAE,CAAA;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAE,OAAe;QACnB,OAAO,IAAI,OAAO,CAAE,CAAE,OAAO,EAAE,MAAM,EAAG,EAAE;;YACxC,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAE,OAAgB,EAAG,EAAE;gBACrD,OAAO,CAAC,CAAC,CAAC,MAAM,CAAE,IAAI,KAAK,CAAE,OAAO,CAAE,CAAE,CAAC,CAAC,CAAC,OAAO,CAAE,IAAI,CAAE,CAAA;YAC5D,CAAC,CAAE,CAAA;QACL,CAAC,CAAE,CAAA;IACL,CAAC;IAED,MAAM,CAAE,EAA0B;;QAChC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAE,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,WAAW,CAAE,EAA0B;;QACrC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAE,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,cAAc,CAAE,EAA0B;;QACxC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;CAkBF;AApED,2BAoEC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/allend/Realtime/index.ts"],"names":[],"mappings":";;;;;AAGA,yEAAgF;AAoChF,MAAqB,QAAS,SAAQ,yBAAc;IAApD;;QACU,OAAE,GAAqB,QAAQ,CAAA;IAoEzC,CAAC;IAlEC,IAAc,KAAK,KAAa,OAAO,IAAI,CAAC,EAAE,CAAA,CAAC,CAAC;IAEhD;;;;;;;OAOG;IACH,OAAO,CAAE,EAAU,EAAE,QAA0B,QAAQ,EAAE,OAAgC;QACvF,IAAI,CAAC,EAAE,GAAG,KAAK,CAAA;QACf,OAAO,IAAI,CAAC,IAAI,CAAE,EAAE,EAAE,OAAO,CAAE,CAAA;IACjC,CAAC;IAED,2EAA2E;IAE3E;;;;;OAKG;IACH,UAAU,CAAE,EAAoC;;QAC9C,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAE,CAAA;QACpC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CAAE,EAA0B;;QACjC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,aAAa,CAAE,EAAyC;;QACtD,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,SAAS,CAAE,EAAgC;;QACzC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,SAAS,EAAE,EAAE,CAAE,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CAAE,OAAgB;;QAC3B,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAE,CAAA;QACnC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,2EAA2E;IAE3E,QAAQ,CAAE,EAA0B;;QAClC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAE,CAAA;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,CAAE,EAA0B;;QAChC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAE,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,WAAW,CAAE,EAA0B;;QACrC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAE,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,cAAc,CAAE,EAA0B;;QACxC,MAAA,IAAI,CAAC,GAAG,0CAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAE,CAAA;QACjC,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AArED,2BAqEC"}
@@ -0,0 +1,61 @@
1
+ import type { AccessOptions } from '../types/access';
2
+ import { Socket } from 'socket.io-client';
3
+ import AccessManager from './Access';
4
+ export type RealtimeConnectOptions = {
5
+ /**
6
+ * A fresh access token for each connection attempt.
7
+ *
8
+ * An app holds tokens it was given rather than credentials it can mint, so
9
+ * this is usually "ask my backend for a new tracking session". Omitted, the
10
+ * token this client was constructed with is used on every attempt, which is
11
+ * correct only for a process that rotates it in place.
12
+ */
13
+ getToken?: () => string | Promise<string>;
14
+ };
15
+ export default abstract class RealtimeSocket extends AccessManager {
16
+ protected nsp?: Socket;
17
+ protected iosHost: string;
18
+ protected id?: string;
19
+ /**
20
+ * Every room this socket asked to be in, by the token that got it there.
21
+ *
22
+ * Kept so a reconnect can restore them. A JRT outlives an ordinary blip, so
23
+ * replaying it is right; when one has expired the rejoin fails and
24
+ * `onRejoinError` is how the app learns to ask for a new session rather than
25
+ * sitting on a silent connection.
26
+ */
27
+ private rooms;
28
+ private rejoinError?;
29
+ constructor(access: AccessOptions);
30
+ /** The `utype` this client connects as. Must match the JRT's `role`. */
31
+ protected abstract get utype(): string;
32
+ protected open(id: string, options?: RealtimeConnectOptions): Promise<void>;
33
+ /** Re-enter every room this socket was in before the connection dropped. */
34
+ private restore;
35
+ /**
36
+ * Enter an order room with a Join Room Token from
37
+ * `GET /v1/tracking/:reference?role=…`.
38
+ */
39
+ join(jrtoken: string): Promise<boolean>;
40
+ /** Stop replaying a room — the order is closed, or the app navigated away. */
41
+ leave(jrtoken: string): void;
42
+ /**
43
+ * A room could not be re-entered after a reconnect.
44
+ *
45
+ * Almost always an expired JRT. The app's answer is to ask its backend for a
46
+ * fresh tracking session and `join` again — and, since it is reconnecting,
47
+ * to `replay` from the `since` that came with it.
48
+ */
49
+ onRejoinError(fn: (error: Error) => void): this;
50
+ /** Fires on every reconnect, which is where a client should replay its gap. */
51
+ onReconnect(fn: () => void): this;
52
+ disconnect(): boolean;
53
+ /**
54
+ * Ask for everything a room emitted while this socket was away.
55
+ *
56
+ * `since` is the timestamp the tracking session came back with, or that of
57
+ * the last event actually seen. Reconnecting without it leaves a hole
58
+ * exactly as long as the outage.
59
+ */
60
+ replay(reference: string, since: number): this;
61
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const socket_io_client_1 = __importDefault(require("socket.io-client"));
7
+ const Access_1 = __importDefault(require("./Access"));
8
+ const baseUrl_1 = require("../baseUrl");
9
+ class RealtimeSocket extends Access_1.default {
10
+ constructor(access) {
11
+ var _a;
12
+ super(access, 'API');
13
+ /**
14
+ * Every room this socket asked to be in, by the token that got it there.
15
+ *
16
+ * Kept so a reconnect can restore them. A JRT outlives an ordinary blip, so
17
+ * replaying it is right; when one has expired the rejoin fails and
18
+ * `onRejoinError` is how the app learns to ask for a new session rather than
19
+ * sitting on a silent connection.
20
+ */
21
+ this.rooms = new Set();
22
+ // Socket.io is served by the same de.arch API server, so an explicit
23
+ // origin governs the socket exactly as it governs the requests.
24
+ this.iosHost = ((_a = access.baseUrl) === null || _a === void 0 ? void 0 : _a.replace(/\/+$/, ''))
25
+ || (0, baseUrl_1.baseURL)('API', access.env || 'dev', access.devHostname);
26
+ }
27
+ open(id, options = {}) {
28
+ this.id = id;
29
+ return new Promise((resolve, reject) => {
30
+ const credentials = async () => ({
31
+ utype: this.utype,
32
+ id,
33
+ remoteOrigin: (globalThis === null || globalThis === void 0 ? void 0 : globalThis.window) ? globalThis.origin : this.remoteOrigin,
34
+ accessToken: options.getToken ? await options.getToken() : this.accessToken
35
+ });
36
+ this.nsp = (0, socket_io_client_1.default)(this.iosHost, {
37
+ // The function form — re-evaluated before every attempt, which is the
38
+ // whole point. The object form is read once, at construction.
39
+ auth: (cb) => {
40
+ credentials()
41
+ .then(cb)
42
+ // A token the app could not fetch is still an attempt: let De.
43
+ // refuse it and surface a connect_error, rather than hanging.
44
+ .catch(() => cb({ utype: this.utype, id }));
45
+ }
46
+ });
47
+ this.nsp.on('connect', () => {
48
+ this.restore();
49
+ resolve();
50
+ });
51
+ this.nsp.on('connect_error', reject);
52
+ });
53
+ }
54
+ /** Re-enter every room this socket was in before the connection dropped. */
55
+ restore() {
56
+ var _a;
57
+ for (const jrtoken of this.rooms)
58
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('JOIN', jrtoken, (errmess) => {
59
+ var _a;
60
+ if (!errmess)
61
+ return;
62
+ this.rooms.delete(jrtoken);
63
+ (_a = this.rejoinError) === null || _a === void 0 ? void 0 : _a.call(this, new Error(errmess));
64
+ });
65
+ }
66
+ /**
67
+ * Enter an order room with a Join Room Token from
68
+ * `GET /v1/tracking/:reference?role=…`.
69
+ */
70
+ join(jrtoken) {
71
+ return new Promise((resolve, reject) => {
72
+ var _a;
73
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('JOIN', jrtoken, (errmess) => {
74
+ if (errmess)
75
+ return reject(new Error(errmess));
76
+ this.rooms.add(jrtoken);
77
+ resolve(true);
78
+ });
79
+ });
80
+ }
81
+ /** Stop replaying a room — the order is closed, or the app navigated away. */
82
+ leave(jrtoken) {
83
+ this.rooms.delete(jrtoken);
84
+ }
85
+ /**
86
+ * A room could not be re-entered after a reconnect.
87
+ *
88
+ * Almost always an expired JRT. The app's answer is to ask its backend for a
89
+ * fresh tracking session and `join` again — and, since it is reconnecting,
90
+ * to `replay` from the `since` that came with it.
91
+ */
92
+ onRejoinError(fn) {
93
+ this.rejoinError = fn;
94
+ return this;
95
+ }
96
+ /** Fires on every reconnect, which is where a client should replay its gap. */
97
+ onReconnect(fn) {
98
+ var _a;
99
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.io.on('reconnect', fn);
100
+ return this;
101
+ }
102
+ disconnect() {
103
+ var _a;
104
+ this.rooms.clear();
105
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.disconnect();
106
+ return true;
107
+ }
108
+ /**
109
+ * Ask for everything a room emitted while this socket was away.
110
+ *
111
+ * `since` is the timestamp the tracking session came back with, or that of
112
+ * the last event actually seen. Reconnecting without it leaves a hole
113
+ * exactly as long as the outage.
114
+ */
115
+ replay(reference, since) {
116
+ var _a;
117
+ (_a = this.nsp) === null || _a === void 0 ? void 0 : _a.emit('REPLAY', { room: `order:${reference}`, since });
118
+ return this;
119
+ }
120
+ }
121
+ exports.default = RealtimeSocket;
122
+ //# sourceMappingURL=realtime-socket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-socket.js","sourceRoot":"","sources":["../../src/allend/realtime-socket.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,20 @@ export type AuthConfig = {
14
14
  * credentials are. Omit it for pure machine-to-machine access.
15
15
  */
16
16
  uid?: string;
17
+ /**
18
+ * Rotate the token ahead of expiry.
19
+ *
20
+ * Off by default, which is the trap: a long-lived process that forgets it
21
+ * works perfectly until the first expiry and then fails every call until
22
+ * it is restarted. Anything holding a token for longer than one request
23
+ * wants this on.
24
+ */
17
25
  autorefresh?: boolean;
26
+ /**
27
+ * Minutes between rotations. Defaults to 3.75 — set it below the De.
28
+ * deployment's `API_ACCESS_TOKEN_EXPIRY` when that is not the default 4.
29
+ */
30
+ rotateAfterMins?: number;
18
31
  onNewToken?: (token: string) => void;
19
32
  /** Host to substitute for `localhost` in `dev` (Eg. a native emulator) */
20
33
  devHostname?: string;
@@ -29,6 +42,7 @@ export default class Auth {
29
42
  private remoteOrigin?;
30
43
  private refreshTimer?;
31
44
  private autorefresh?;
45
+ private rotateAfterMins;
32
46
  private onNewToken?;
33
47
  private baseURL;
34
48
  private isRotating;
@@ -1,7 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const baseUrl_1 = require("../baseUrl");
4
- const ACCESS_TOKEN_EXPIRY = 3.75; // in 3 minutes 45 seconds
4
+ /**
5
+ * When to rotate, in minutes.
6
+ *
7
+ * De.'s own default token life is four minutes, so this beats it by fifteen
8
+ * seconds. It is a default and not a constant because the server's life is
9
+ * configurable — `API_ACCESS_TOKEN_EXPIRY` — and these two numbers are
10
+ * otherwise free to drift apart in the direction that breaks: a deployment
11
+ * that shortens the token to two minutes leaves every client rotating a
12
+ * credential that expired ninety seconds ago, and every call in between is
13
+ * answered 401 with nothing to say why.
14
+ */
15
+ const ACCESS_TOKEN_EXPIRY = 3.75;
5
16
  class Auth {
6
17
  constructor(config) {
7
18
  this.isRotating = false;
@@ -22,6 +33,9 @@ class Auth {
22
33
  this.version = config.version || 1;
23
34
  this.baseURL = (0, baseUrl_1.baseURL)('API', this.env, config.devHostname);
24
35
  this.autorefresh = config.autorefresh || false;
36
+ this.rotateAfterMins = config.rotateAfterMins && config.rotateAfterMins > 0
37
+ ? config.rotateAfterMins
38
+ : ACCESS_TOKEN_EXPIRY;
25
39
  this.onNewToken = config.onNewToken;
26
40
  }
27
41
  async request({ url, ...options }) {
@@ -57,7 +71,7 @@ class Auth {
57
71
  if (!this.autorefresh)
58
72
  return;
59
73
  this.clearRotation();
60
- this.refreshTimer = setTimeout(() => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000);
74
+ this.refreshTimer = setTimeout(() => this.rotateToken(), this.rotateAfterMins * 60 * 1000);
61
75
  }
62
76
  /**
63
77
  * Clear rotation timer
@@ -1 +1 @@
1
- {"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Auth.js","sourceRoot":"","sources":["../../src/backend/Auth.ts"],"names":[],"mappings":"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"}
package/dist/core.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { default as Auth } from './backend/Auth';
2
2
  export type { AuthConfig } from './backend/Auth';
3
+ export type { RealtimeConnectOptions } from './allend/realtime-socket';
4
+ export type { RealtimeUserType } from './allend/Realtime';
3
5
  export { default as OTPAuth } from './allend/OTPAuth';
4
6
  export { default as Tracking } from './allend/Tracking';
5
7
  export type { TrackingConfig } from './allend/Tracking';
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,WAAW;AACX,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,EAAE;AACF,gFAAgF;;;;;;AAEhF,iFAAiF;AAEjF,yDAAyD;AACzD,uCAAgD;AAAvC,6GAAA,OAAO,OAAQ;AAGxB,yCAAyC;AACzC,4CAAqD;AAA5C,mHAAA,OAAO,OAAW;AAE3B,0CAA0C;AAC1C,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAG5B,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,qEAAqE;AACrE,wCAA+E;AAAtE,+GAAA,OAAO,OAAS;AAAE,0GAAA,OAAO,OAAqB;AAGvD,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,4CAA4C;AAC5C,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAE5B,sBAAsB;AACtB,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,YAAY;AACZ,iCAA0C;AAAjC,+GAAA,OAAO,OAAS;AAEzB,iCAA6C;AAApC,kHAAA,OAAO,OAAY;AAC5B,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA;AAEjB,iFAAiF;AACjF,8EAA8E;AAC9E,kBAAkB;AAClB,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,sDAAsD;AACtD,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAG5B,wCAAiD;AAAxC,+GAAA,OAAO,OAAS;AAIzB,4CAAqD;AAA5C,mHAAA,OAAO,OAAW;AAG3B,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAe7B,iFAAiF;AAEjF,0DAAsC;AACtC,+DAAwC;AACxC,mEAA0C;AAC1C,iEAAyC;AACzC,qEAA8C;AAC9C,uDAAoC;AACpC,uDAAoC;AACpC,uDAAoC;AACpC,2DAAsC;AACtC,mEAA0C;AAC1C,mEAA0C;AAC1C,iEAAyC;AACzC,oDAA+B;AAC/B,mEAA0C;AAC1C,iEAAyC;AACzC,2DAAsC;AACtC,+DAAwC;AACxC,mEAA0C;AAC1C,uEAAiD;AACjD,iEAAyC;AAEzC,qEAAqE;AACrE,MAAM,OAAO,GAAG,EAAE,MAAM,EAAN,gBAAM,EAAE,KAAK,EAAL,kBAAK,EAAE,CAAA;AACxB,0BAAO;AAEH,QAAA,IAAI,GAAG;IACnB,IAAI,EAAJ,cAAI;IACJ,OAAO,EAAP,iBAAO;IACP,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,GAAG,EAAH,iBAAG;IACH,GAAG,EAAH,aAAG;IACH,GAAG,EAAH,aAAG;IACH,GAAG,EAAH,aAAG;IACH,KAAK,EAAL,eAAK;IACL,SAAS,EAAT,mBAAS;IACT,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,KAAK,EAAL,eAAK;IACL,OAAO;IACP,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,KAAK,EAAL,eAAK;IACL,OAAO,EAAP,iBAAO;IACP,SAAS,EAAT,mBAAS;CACT,CAAA"}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";AAAA,iFAAiF;AACjF,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,0EAA0E;AAC1E,WAAW;AACX,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,EAAE;AACF,gFAAgF;;;;;;AAEhF,iFAAiF;AAEjF,yDAAyD;AACzD,uCAAgD;AAAvC,6GAAA,OAAO,OAAQ;AAOxB,yCAAyC;AACzC,4CAAqD;AAA5C,mHAAA,OAAO,OAAW;AAE3B,0CAA0C;AAC1C,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAG5B,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,oCAA6C;AAApC,2GAAA,OAAO,OAAO;AAGvB,qEAAqE;AACrE,wCAA+E;AAAtE,+GAAA,OAAO,OAAS;AAAE,0GAAA,OAAO,OAAqB;AAGvD,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,4CAA4C;AAC5C,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAE5B,sBAAsB;AACtB,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,YAAY;AACZ,iCAA0C;AAAjC,+GAAA,OAAO,OAAS;AAEzB,iCAA6C;AAApC,kHAAA,OAAO,OAAY;AAC5B,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA;AAEjB,iFAAiF;AACjF,8EAA8E;AAC9E,kBAAkB;AAClB,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,sDAAsD;AACtD,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAG7B,8CAAuD;AAA9C,qHAAA,OAAO,OAAY;AAG5B,wCAAiD;AAAxC,+GAAA,OAAO,OAAS;AAIzB,4CAAqD;AAA5C,mHAAA,OAAO,OAAW;AAG3B,gDAAyD;AAAhD,uHAAA,OAAO,OAAa;AAe7B,iFAAiF;AAEjF,0DAAsC;AACtC,+DAAwC;AACxC,mEAA0C;AAC1C,iEAAyC;AACzC,qEAA8C;AAC9C,uDAAoC;AACpC,uDAAoC;AACpC,uDAAoC;AACpC,2DAAsC;AACtC,mEAA0C;AAC1C,mEAA0C;AAC1C,iEAAyC;AACzC,oDAA+B;AAC/B,mEAA0C;AAC1C,iEAAyC;AACzC,2DAAsC;AACtC,+DAAwC;AACxC,mEAA0C;AAC1C,uEAAiD;AACjD,iEAAyC;AAEzC,qEAAqE;AACrE,MAAM,OAAO,GAAG,EAAE,MAAM,EAAN,gBAAM,EAAE,KAAK,EAAL,kBAAK,EAAE,CAAA;AACxB,0BAAO;AAEH,QAAA,IAAI,GAAG;IACnB,IAAI,EAAJ,cAAI;IACJ,OAAO,EAAP,iBAAO;IACP,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,GAAG,EAAH,iBAAG;IACH,GAAG,EAAH,aAAG;IACH,GAAG,EAAH,aAAG;IACH,GAAG,EAAH,aAAG;IACH,KAAK,EAAL,eAAK;IACL,SAAS,EAAT,mBAAS;IACT,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,KAAK,EAAL,eAAK;IACL,OAAO;IACP,SAAS,EAAT,mBAAS;IACT,QAAQ,EAAR,kBAAQ;IACR,KAAK,EAAL,eAAK;IACL,OAAO,EAAP,iBAAO;IACP,SAAS,EAAT,mBAAS;CACT,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@de./sdk",
3
- "version": "2.1.1",
3
+ "version": "2.2.1",
4
4
  "description": "Complete SDK pack for MSI (Map Service Interface), IoTClient and DClient services — web, server and React Native",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -41,7 +41,7 @@
41
41
  "test:event": "npm run build:tsc && jest test/event.test.js"
42
42
  },
43
43
  "dependencies": {
44
- "@de./types": "^2.1.0",
44
+ "@de./types": "^2.2.0",
45
45
  "events": "^3.3.0",
46
46
  "iframe.io": "^1.3.0",
47
47
  "node-fetch": "2.6.1",
@@ -1,11 +1,7 @@
1
1
  import type { OrderTrackingEvent } from '@de./types'
2
2
  import type { RTLocation, Message, Peer } from '../../types'
3
- import type { SocketAuthCredentials } from '../../types/auth'
4
- import type { AccessOptions } from '../../types/access'
5
3
 
6
- import io, { Socket } from 'socket.io-client'
7
- import AccessManager from '../Access'
8
- import { baseURL } from '../../baseUrl'
4
+ import RealtimeSocket, { type RealtimeConnectOptions } from '../realtime-socket'
9
5
 
10
6
  // ─── Agent Realtime ───────────────────────────────────────────────────────────
11
7
  //
@@ -32,53 +28,20 @@ export type AgentRealtimeContext = {
32
28
  xcode: string
33
29
  }
34
30
 
35
- export default class AgentRealtime extends AccessManager {
36
- private nsp?: Socket
37
- private iosHost: string
31
+ export default class AgentRealtime extends RealtimeSocket {
38
32
  private agentId?: string
39
33
 
40
- constructor( access: AccessOptions ){
41
- super( access, 'API' )
42
-
43
- // Socket.io is served by the same de.arch API server, so an explicit
44
- // origin governs the socket exactly as it governs the requests — without
45
- // this, a client pointed at a self-hosted De. still opened its socket
46
- // against the environment table's host.
47
- this.iosHost = access.baseUrl?.replace( /\/+$/, '' )
48
- || baseURL('API', access.env || 'dev', access.devHostname )
49
- }
50
-
51
- connect( agentId: string ): Promise<void> {
52
- return new Promise( ( resolve, reject ) => {
53
- const auth: SocketAuthCredentials = {
54
- utype: 'agent',
55
- id: agentId,
56
- remoteOrigin: this.remoteOrigin as string,
57
- accessToken: this.accessToken as string
58
- }
59
-
60
- this.agentId = agentId
61
- this.nsp = io( this.iosHost, { auth } )
62
- this.nsp.on('connect', resolve )
63
- this.nsp.on('connect_error', reject )
64
- } )
65
- }
66
-
67
- disconnect(){
68
- this.nsp?.disconnect()
69
- return true
70
- }
34
+ protected get utype(): string { return 'agent' }
71
35
 
72
36
  /**
73
- * Join an order tracking room with a Join Room Token issued by
74
- * GET /v1/tracking/:reference (role must match this socket's utype)
37
+ * @param options `getToken` supplies a fresh access token per attempt. A
38
+ * rider's phone reconnects constantly and De.'s tokens are
39
+ * short-lived, so without it the socket comes back refused —
40
+ * or, worse, comes back connected and in none of its rooms.
75
41
  */
76
- join( jrtoken: string ): Promise<boolean> {
77
- return new Promise( ( resolve, reject ) => {
78
- this.nsp?.emit('JOIN', jrtoken, ( errmess?: string ) => {
79
- errmess ? reject( new Error( errmess ) ) : resolve( true )
80
- } )
81
- } )
42
+ connect( agentId: string, options?: RealtimeConnectOptions ): Promise<void> {
43
+ this.agentId = agentId
44
+ return this.open( agentId, options )
82
45
  }
83
46
 
84
47
  // ── Order room streams (after join) ─────────────────────────────────────
@@ -1,50 +1,99 @@
1
- import type { RTLocation , Message, Peer } from '../../types'
2
- import type { SocketAuthCredentials } from '../../types/auth'
3
- import type { AccessOptions } from '../../types/access'
1
+ import type { OrderTrackingEvent } from '@de./types'
2
+ import type { RTLocation, Message, Peer } from '../../types'
4
3
 
5
- import io, { Socket } from 'socket.io-client'
6
- import AccessManager from '../Access'
7
- import { baseURL } from '../../baseUrl'
4
+ import RealtimeSocket, { type RealtimeConnectOptions } from '../realtime-socket'
8
5
 
9
- export default class Realtime extends AccessManager {
10
- private nsp?: Socket
11
- private iosHost: string
6
+ // ─── Realtime ─────────────────────────────────────────────────────────────────
7
+ //
8
+ // The non-agent side of an order room: the person waiting for the delivery,
9
+ // the merchant who dispatched it, or a platform's own client connection.
10
+ //
11
+ // The flow is two steps and they are not interchangeable:
12
+ //
13
+ // connect( id, utype ) opens the socket. `id` is the uid the tracking
14
+ // session was minted for, and `utype` must match the
15
+ // `role` it was minted with.
16
+ // join( jrtoken ) enters the order's room.
17
+ //
18
+ // De. checks the second against the first — the JRT's seal is `role:uid`, and
19
+ // JOIN compares it to the connection's own `utype:id`. Connecting as one
20
+ // person and presenting another's token is refused, and so is connecting as
21
+ // 'client' with a token minted for role 'customer', which is what this client
22
+ // used to do unconditionally.
23
+ //
24
+ // Distinct from `AgentRealtime` (allend/Agent/realtime), which is the rider's
25
+ // socket and carries the consolidation response channel as well.
26
+ //
27
+ // ─────────────────────────────────────────────────────────────────────────────
12
28
 
13
- constructor( access: AccessOptions ){
14
- super( access, 'API' )
15
- // Socket server host
16
- // An explicit origin governs the socket as it governs the requests.
17
- this.iosHost = access.baseUrl?.replace( /\/+$/, '' )
18
- || baseURL('RTS', access.env, access.devHostname )
29
+ /**
30
+ * Who this connection is, in De.'s vocabulary.
31
+ *
32
+ * A client is the party that engaged the provider — a CSP, a merchant, a
33
+ * branch. A customer is the person the delivery is handed to. They are not
34
+ * the same party and De. does not put them in the same room, so a customer
35
+ * app connecting as 'client' hears nothing addressed to customers and cannot
36
+ * redeem a customer's tracking token.
37
+ */
38
+ export type RealtimeUserType = 'client' | 'customer' | 'vendor'
39
+
40
+ export default class Realtime extends RealtimeSocket {
41
+ private as: RealtimeUserType = 'client'
42
+
43
+ protected get utype(): string { return this.as }
44
+
45
+ /**
46
+ * @param id The uid the tracking session was issued for.
47
+ * @param utype Must equal the `role` that session was issued with.
48
+ * @param options `getToken` supplies a fresh access token per attempt —
49
+ * without it a reconnect after the token's short life is
50
+ * refused, and the app is left with an open socket that
51
+ * delivers nothing.
52
+ */
53
+ connect( id: string, utype: RealtimeUserType = 'client', options?: RealtimeConnectOptions ): Promise<void> {
54
+ this.as = utype
55
+ return this.open( id, options )
19
56
  }
20
57
 
21
- connect( clientId: string ): Promise<void> {
22
- return new Promise( ( resolve, reject ) => {
23
- // Connect to main clients namespace
24
- const auth: SocketAuthCredentials = {
25
- utype: 'client',
26
- id: clientId,
27
- remoteOrigin: globalThis?.window ? globalThis.origin : this.remoteOrigin as string,
28
- accessToken: this.accessToken as string
29
- }
30
-
31
- this.nsp = io( this.iosHost, { auth } )
32
- this.nsp.on('connect', resolve )
33
- this.nsp.on('connect_error', reject )
34
- } )
58
+ // ── Order room streams (after join) ─────────────────────────────────────
59
+
60
+ /**
61
+ * The rider's position, as it moves.
62
+ *
63
+ * Rate-limited by De. to 10 per second per sender, so this is a stream and
64
+ * not a trickle: render from it directly rather than re-fetching anything.
65
+ */
66
+ onLocation( fn: ( location: RTLocation ) => void ){
67
+ this.nsp?.on('LOCATION-CHANGE', fn )
68
+ return this
35
69
  }
36
- disconnect(){
37
- this.nsp?.disconnect()
38
- return true
70
+
71
+ onRoute( fn: ( route: any ) => void ){
72
+ this.nsp?.on('ROUTE-CHANGE', fn )
73
+ return this
39
74
  }
40
- join( jrtoken: string ): Promise<boolean> {
41
- return new Promise( ( resolve, reject ) => {
42
- this.nsp?.emit('JOIN', jrtoken, ( errmess?: string ) => {
43
- errmess ? reject( new Error( errmess ) ) : resolve( true )
44
- } )
45
- } )
75
+
76
+ onOrderUpdate( fn: ( event: OrderTrackingEvent ) => void ){
77
+ this.nsp?.on('ORDER_UPDATE', fn )
78
+ return this
46
79
  }
47
80
 
81
+ onMessage( fn: ( message: Message ) => void ){
82
+ this.nsp?.on('MESSAGE', fn )
83
+ return this
84
+ }
85
+
86
+ sendMessage( message: Message ){
87
+ this.nsp?.emit('MESSAGE', message )
88
+ return this
89
+ }
90
+
91
+ // ── Presence ────────────────────────────────────────────────────────────
92
+
93
+ onJoined( fn: ( peer: Peer ) => void ){
94
+ this.nsp?.on('JOINED', fn )
95
+ return this
96
+ }
48
97
  onLeft( fn: ( peer: Peer ) => void ){
49
98
  this.nsp?.on('LEFT', fn )
50
99
  return this
@@ -57,21 +106,4 @@ export default class Realtime extends AccessManager {
57
106
  this.nsp?.on('DISCONNECTED', fn )
58
107
  return this
59
108
  }
60
-
61
- // onRoute( fn: ( data: any ) => void ){
62
- // this.nsp?.on('ROUTE-CHANGE', fn )
63
- // return this
64
- // }
65
- // onStage( fn: ( data: OrderStage ) => void ){
66
- // this.nsp?.on('STAGE-CHANGE', fn )
67
- // return this
68
- // }
69
- // onLocation( fn: ( location: RTLocation ) => void ){
70
- // this.nsp?.on('LOCATION-CHANGE', fn )
71
- // return this
72
- // }
73
- // onMessage( fn: ( payload: Message ) => void ){
74
- // this.nsp?.on('MESSAGE', fn )
75
- // return this
76
- // }
77
- }
109
+ }
@@ -0,0 +1,171 @@
1
+ import type { SocketAuthCredentials } from '../types/auth'
2
+ import type { AccessOptions } from '../types/access'
3
+
4
+ import io, { Socket } from 'socket.io-client'
5
+ import AccessManager from './Access'
6
+ import { baseURL } from '../baseUrl'
7
+
8
+ // ─── RealtimeSocket ───────────────────────────────────────────────────────────
9
+ //
10
+ // What `Realtime` and `AgentRealtime` share: opening the connection, and
11
+ // getting back into the rooms afterwards.
12
+ //
13
+ // Both used to hand socket.io a plain object for `auth` and call `join` once,
14
+ // which works exactly until the first reconnect — and on a phone the first
15
+ // reconnect is a lift doorway. Two things break there, both silently:
16
+ //
17
+ // · The token. socket.io captures the auth literal once and replays it on
18
+ // every attempt. De.'s access tokens are short-lived, so the replayed one
19
+ // is stale precisely on the reconnect after an outage long enough to have
20
+ // crossed an expiry. De. refuses the handshake — and until 2026-09-08 that
21
+ // refusal took de.arch's whole process down with it.
22
+ //
23
+ // · The rooms. Room membership is per-connection and De. does not restore
24
+ // it. A reconnected socket is connected to the server and in none of the
25
+ // rooms it was in, so it stays open, reports itself healthy, and delivers
26
+ // nothing. That is the worse of the two failures because nothing anywhere
27
+ // reports it.
28
+ //
29
+ // So `auth` is a function, evaluated per attempt, and every join is remembered
30
+ // and replayed.
31
+ //
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+
34
+ export type RealtimeConnectOptions = {
35
+ /**
36
+ * A fresh access token for each connection attempt.
37
+ *
38
+ * An app holds tokens it was given rather than credentials it can mint, so
39
+ * this is usually "ask my backend for a new tracking session". Omitted, the
40
+ * token this client was constructed with is used on every attempt, which is
41
+ * correct only for a process that rotates it in place.
42
+ */
43
+ getToken?: () => string | Promise<string>
44
+ }
45
+
46
+ export default abstract class RealtimeSocket extends AccessManager {
47
+ protected nsp?: Socket
48
+ protected iosHost: string
49
+ protected id?: string
50
+
51
+ /**
52
+ * Every room this socket asked to be in, by the token that got it there.
53
+ *
54
+ * Kept so a reconnect can restore them. A JRT outlives an ordinary blip, so
55
+ * replaying it is right; when one has expired the rejoin fails and
56
+ * `onRejoinError` is how the app learns to ask for a new session rather than
57
+ * sitting on a silent connection.
58
+ */
59
+ private rooms = new Set<string>()
60
+ private rejoinError?: ( error: Error ) => void
61
+
62
+ constructor( access: AccessOptions ){
63
+ super( access, 'API' )
64
+
65
+ // Socket.io is served by the same de.arch API server, so an explicit
66
+ // origin governs the socket exactly as it governs the requests.
67
+ this.iosHost = access.baseUrl?.replace( /\/+$/, '' )
68
+ || baseURL('API', access.env || 'dev', access.devHostname )
69
+ }
70
+
71
+ /** The `utype` this client connects as. Must match the JRT's `role`. */
72
+ protected abstract get utype(): string
73
+
74
+ protected open( id: string, options: RealtimeConnectOptions = {} ): Promise<void> {
75
+ this.id = id
76
+
77
+ return new Promise( ( resolve, reject ) => {
78
+ const credentials = async (): Promise<SocketAuthCredentials> => ({
79
+ utype: this.utype,
80
+ id,
81
+ remoteOrigin: globalThis?.window ? globalThis.origin : this.remoteOrigin as string,
82
+ accessToken: options.getToken ? await options.getToken() : this.accessToken as string
83
+ })
84
+
85
+ this.nsp = io( this.iosHost, {
86
+ // The function form — re-evaluated before every attempt, which is the
87
+ // whole point. The object form is read once, at construction.
88
+ auth: ( cb: ( data: any ) => void ) => {
89
+ credentials()
90
+ .then( cb )
91
+ // A token the app could not fetch is still an attempt: let De.
92
+ // refuse it and surface a connect_error, rather than hanging.
93
+ .catch( () => cb({ utype: this.utype, id }) )
94
+ }
95
+ })
96
+
97
+ this.nsp.on('connect', () => {
98
+ this.restore()
99
+ resolve()
100
+ })
101
+ this.nsp.on('connect_error', reject )
102
+ })
103
+ }
104
+
105
+ /** Re-enter every room this socket was in before the connection dropped. */
106
+ private restore(): void {
107
+ for( const jrtoken of this.rooms )
108
+ this.nsp?.emit('JOIN', jrtoken, ( errmess?: string ) => {
109
+ if( !errmess ) return
110
+
111
+ this.rooms.delete( jrtoken )
112
+ this.rejoinError?.( new Error( errmess ) )
113
+ })
114
+ }
115
+
116
+ /**
117
+ * Enter an order room with a Join Room Token from
118
+ * `GET /v1/tracking/:reference?role=…`.
119
+ */
120
+ join( jrtoken: string ): Promise<boolean> {
121
+ return new Promise( ( resolve, reject ) => {
122
+ this.nsp?.emit('JOIN', jrtoken, ( errmess?: string ) => {
123
+ if( errmess ) return reject( new Error( errmess ) )
124
+
125
+ this.rooms.add( jrtoken )
126
+ resolve( true )
127
+ })
128
+ })
129
+ }
130
+
131
+ /** Stop replaying a room — the order is closed, or the app navigated away. */
132
+ leave( jrtoken: string ): void {
133
+ this.rooms.delete( jrtoken )
134
+ }
135
+
136
+ /**
137
+ * A room could not be re-entered after a reconnect.
138
+ *
139
+ * Almost always an expired JRT. The app's answer is to ask its backend for a
140
+ * fresh tracking session and `join` again — and, since it is reconnecting,
141
+ * to `replay` from the `since` that came with it.
142
+ */
143
+ onRejoinError( fn: ( error: Error ) => void ){
144
+ this.rejoinError = fn
145
+ return this
146
+ }
147
+
148
+ /** Fires on every reconnect, which is where a client should replay its gap. */
149
+ onReconnect( fn: () => void ){
150
+ this.nsp?.io.on('reconnect', fn )
151
+ return this
152
+ }
153
+
154
+ disconnect(){
155
+ this.rooms.clear()
156
+ this.nsp?.disconnect()
157
+ return true
158
+ }
159
+
160
+ /**
161
+ * Ask for everything a room emitted while this socket was away.
162
+ *
163
+ * `since` is the timestamp the tracking session came back with, or that of
164
+ * the last event actually seen. Reconnecting without it leaves a hole
165
+ * exactly as long as the outage.
166
+ */
167
+ replay( reference: string, since: number ){
168
+ this.nsp?.emit('REPLAY', { room: `order:${reference}`, since })
169
+ return this
170
+ }
171
+ }
@@ -1,7 +1,18 @@
1
1
  import { baseURL } from '../baseUrl'
2
2
  import type { AuthRequestOptions } from '../types/auth'
3
3
 
4
- const ACCESS_TOKEN_EXPIRY = 3.75 // in 3 minutes 45 seconds
4
+ /**
5
+ * When to rotate, in minutes.
6
+ *
7
+ * De.'s own default token life is four minutes, so this beats it by fifteen
8
+ * seconds. It is a default and not a constant because the server's life is
9
+ * configurable — `API_ACCESS_TOKEN_EXPIRY` — and these two numbers are
10
+ * otherwise free to drift apart in the direction that breaks: a deployment
11
+ * that shortens the token to two minutes leaves every client rotating a
12
+ * credential that expired ninety seconds ago, and every call in between is
13
+ * answered 401 with nothing to say why.
14
+ */
15
+ const ACCESS_TOKEN_EXPIRY = 3.75
5
16
 
6
17
  // ─── Config ───────────────────────────────────────────────────────────────────
7
18
  //
@@ -27,7 +38,20 @@ export type AuthConfig = {
27
38
  * credentials are. Omit it for pure machine-to-machine access.
28
39
  */
29
40
  uid?: string
41
+ /**
42
+ * Rotate the token ahead of expiry.
43
+ *
44
+ * Off by default, which is the trap: a long-lived process that forgets it
45
+ * works perfectly until the first expiry and then fails every call until
46
+ * it is restarted. Anything holding a token for longer than one request
47
+ * wants this on.
48
+ */
30
49
  autorefresh?: boolean
50
+ /**
51
+ * Minutes between rotations. Defaults to 3.75 — set it below the De.
52
+ * deployment's `API_ACCESS_TOKEN_EXPIRY` when that is not the default 4.
53
+ */
54
+ rotateAfterMins?: number
31
55
  onNewToken?: ( token: string ) => void
32
56
  /** Host to substitute for `localhost` in `dev` (Eg. a native emulator) */
33
57
  devHostname?: string
@@ -51,6 +75,7 @@ export default class Auth {
51
75
  private remoteOrigin?: string
52
76
  private refreshTimer?: NodeJS.Timeout
53
77
  private autorefresh?: boolean
78
+ private rotateAfterMins: number
54
79
  private onNewToken?: (token: string) => void
55
80
  private baseURL: string
56
81
  private isRotating: boolean = false
@@ -71,6 +96,9 @@ export default class Auth {
71
96
  this.version = config.version || 1
72
97
  this.baseURL = baseURL('API', this.env, config.devHostname )
73
98
  this.autorefresh = config.autorefresh || false
99
+ this.rotateAfterMins = config.rotateAfterMins && config.rotateAfterMins > 0
100
+ ? config.rotateAfterMins
101
+ : ACCESS_TOKEN_EXPIRY
74
102
  this.onNewToken = config.onNewToken
75
103
  }
76
104
 
@@ -114,7 +142,7 @@ export default class Auth {
114
142
  if( !this.autorefresh ) return
115
143
 
116
144
  this.clearRotation()
117
- this.refreshTimer = setTimeout( () => this.rotateToken(), ACCESS_TOKEN_EXPIRY * 60 * 1000 )
145
+ this.refreshTimer = setTimeout( () => this.rotateToken(), this.rotateAfterMins * 60 * 1000 )
118
146
  }
119
147
 
120
148
  /**
package/src/core.ts CHANGED
@@ -22,6 +22,10 @@
22
22
  export { default as Auth } from './backend/Auth'
23
23
  export type { AuthConfig } from './backend/Auth'
24
24
 
25
+ // Order-room sockets — shared connect/rejoin behaviour
26
+ export type { RealtimeConnectOptions } from './allend/realtime-socket'
27
+ export type { RealtimeUserType } from './allend/Realtime'
28
+
25
29
  // Client-side OTP auth (de.auth service)
26
30
  export { default as OTPAuth } from './allend/OTPAuth'
27
31