@dxos/protocols 2.33.8-dev.8609bc45 → 2.33.9-dev.002e8917
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/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/proto/gen/dxos/bot.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/bot.js.map +1 -1
- package/dist/src/proto/gen/dxos/client.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/client.js.map +1 -1
- package/dist/src/proto/gen/dxos/config.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/config.js.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/auth.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/greet.d.ts +1 -1
- package/dist/src/proto/gen/dxos/credentials/greet.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/greet.js.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/identity.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/party.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/credentials/party.js.map +1 -1
- package/dist/src/proto/gen/dxos/credentials.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/devtools.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/feed.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/feed.js.map +1 -1
- package/dist/src/proto/gen/dxos/echo/invitation.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/invitation.js.map +1 -1
- package/dist/src/proto/gen/dxos/echo/metadata.d.ts +6 -5
- package/dist/src/proto/gen/dxos/echo/metadata.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/service.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/snapshot.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/echo/timeframe.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/halo/keys.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/halo/keys.js.map +1 -1
- package/dist/src/proto/gen/dxos/rpc.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/rpc.js.map +1 -1
- package/dist/src/proto/gen/dxos/test/echo.d.ts +11 -0
- package/dist/src/proto/gen/dxos/test/echo.d.ts.map +1 -0
- package/dist/src/proto/gen/dxos/test/echo.js +3 -0
- package/dist/src/proto/gen/dxos/test/echo.js.map +1 -0
- package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
- package/dist/src/proto/gen/google/protobuf.js.map +1 -1
- package/dist/src/proto/gen/index.d.ts +4 -0
- package/dist/src/proto/gen/index.d.ts.map +1 -1
- package/dist/src/proto/gen/index.js +1 -1
- package/dist/src/proto/gen/index.js.map +1 -1
- package/dist/src/proto/index.d.ts +0 -1
- package/dist/src/proto/index.d.ts.map +1 -1
- package/dist/src/proto/index.js +0 -16
- package/dist/src/proto/index.js.map +1 -1
- package/dist/src/public-key.d.ts +21 -2
- package/dist/src/public-key.d.ts.map +1 -1
- package/dist/src/public-key.js +62 -4
- package/dist/src/public-key.js.map +1 -1
- package/dist/src/public-key.test.js +7 -0
- package/dist/src/public-key.test.js.map +1 -1
- package/dist/src/timeframe.d.ts +57 -0
- package/dist/src/timeframe.d.ts.map +1 -0
- package/dist/src/timeframe.js +127 -0
- package/dist/src/timeframe.js.map +1 -0
- package/dist/src/timeframe.test.d.ts +2 -0
- package/dist/src/timeframe.test.d.ts.map +1 -0
- package/dist/src/timeframe.test.js +113 -0
- package/dist/src/timeframe.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -5
- package/src/index.ts +1 -1
- package/src/proto/dxos/echo/metadata.proto +10 -7
- package/src/proto/dxos/halo/greet.proto +1 -2
- package/src/proto/dxos/test/echo.proto +20 -0
- package/src/proto/gen/dxos/bot.ts +1 -0
- package/src/proto/gen/dxos/client.ts +1 -0
- package/src/proto/gen/dxos/config.ts +1 -0
- package/src/proto/gen/dxos/credentials/auth.ts +1 -0
- package/src/proto/gen/dxos/credentials/greet.ts +2 -1
- package/src/proto/gen/dxos/credentials/identity.ts +1 -0
- package/src/proto/gen/dxos/credentials/party.ts +1 -0
- package/src/proto/gen/dxos/credentials.ts +1 -0
- package/src/proto/gen/dxos/devtools.ts +1 -0
- package/src/proto/gen/dxos/echo/feed.ts +1 -0
- package/src/proto/gen/dxos/echo/invitation.ts +1 -0
- package/src/proto/gen/dxos/echo/metadata.ts +7 -5
- package/src/proto/gen/dxos/echo/service.ts +1 -0
- package/src/proto/gen/dxos/echo/snapshot.ts +1 -0
- package/src/proto/gen/dxos/echo/timeframe.ts +1 -0
- package/src/proto/gen/dxos/halo/keys.ts +1 -0
- package/src/proto/gen/dxos/rpc.ts +1 -0
- package/src/proto/gen/dxos/test/echo.ts +29 -0
- package/src/proto/gen/google/protobuf.ts +1 -0
- package/src/proto/gen/index.ts +5 -1
- package/src/proto/index.ts +0 -2
- package/src/public-key.test.ts +10 -0
- package/src/public-key.ts +69 -3
- package/src/timeframe.test.ts +125 -0
- package/src/timeframe.ts +144 -0
package/src/public-key.ts
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
// Copyright 2020 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import assert from 'node:assert';
|
|
6
|
+
import { inspect, InspectOptionsStylized } from 'node:util';
|
|
5
7
|
import randomBytes from 'randombytes';
|
|
6
|
-
import { inspect } from 'util';
|
|
7
8
|
|
|
9
|
+
export const PUBLIC_KEY_LENGTH = 32;
|
|
10
|
+
export const SECRET_KEY_LENGTH = 64;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The purpose of this class is to assure consistent use of keys throughout the project.
|
|
14
|
+
* Keys should be maintained as buffers in objects and proto definitions, and converted to hex
|
|
15
|
+
* strings as late as possible (eg, to log/display).
|
|
16
|
+
*/
|
|
8
17
|
export class PublicKey {
|
|
9
18
|
/**
|
|
10
19
|
* Creates new instance of PublicKey automatically determining the input format.
|
|
@@ -63,6 +72,35 @@ export class PublicKey {
|
|
|
63
72
|
return PublicKey.from(left).equals(right);
|
|
64
73
|
}
|
|
65
74
|
|
|
75
|
+
/**
|
|
76
|
+
* @param Hex string representation of key.
|
|
77
|
+
* @return Key buffer.
|
|
78
|
+
* @deprecated All keys should be represented as instances of PublicKey.
|
|
79
|
+
*/
|
|
80
|
+
static bufferize (str: string): Buffer {
|
|
81
|
+
assert(typeof str === 'string', 'Invalid type');
|
|
82
|
+
const buffer = Buffer.from(str, 'hex');
|
|
83
|
+
assert(buffer.length === PUBLIC_KEY_LENGTH || buffer.length === SECRET_KEY_LENGTH,
|
|
84
|
+
`Invalid key length: ${buffer.length}`);
|
|
85
|
+
return buffer;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @param Public key like data structure (but not PublicKey which should use toString).
|
|
90
|
+
* @return Hex string representation of key.
|
|
91
|
+
* @deprecated All keys should be represented as instances of PublicKey.
|
|
92
|
+
*/
|
|
93
|
+
static stringify (key: Buffer | Uint8Array): string {
|
|
94
|
+
if (key instanceof PublicKey) {
|
|
95
|
+
key = key.asBuffer();
|
|
96
|
+
} else if (key instanceof Uint8Array) {
|
|
97
|
+
key = Buffer.from(key);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
assert(key instanceof Buffer, 'Invalid type');
|
|
101
|
+
return key.toString('hex');
|
|
102
|
+
}
|
|
103
|
+
|
|
66
104
|
constructor (
|
|
67
105
|
private readonly _value: Uint8Array
|
|
68
106
|
) {
|
|
@@ -118,8 +156,36 @@ export class PublicKey {
|
|
|
118
156
|
/**
|
|
119
157
|
* Used by NodeJS to get textual representation of this object when it's printed with a `console.log` statement.
|
|
120
158
|
*/
|
|
121
|
-
[inspect.custom] () {
|
|
122
|
-
|
|
159
|
+
[inspect.custom] (depth: number, options: InspectOptionsStylized) {
|
|
160
|
+
if (!options.colors || !process.stdout.hasColors()) {
|
|
161
|
+
return `<PublicKey ${this.truncate()}>`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const printControlCode = (code: number) => {
|
|
165
|
+
return `\x1b[${code}m`;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Compute simple hash of the key.
|
|
169
|
+
const hash = Math.abs(this._value.reduce((acc, val) => acc ^ val | 0, 0));
|
|
170
|
+
|
|
171
|
+
const colors = [
|
|
172
|
+
'red',
|
|
173
|
+
'green',
|
|
174
|
+
'yellow',
|
|
175
|
+
'blue',
|
|
176
|
+
'magenta',
|
|
177
|
+
'cyan',
|
|
178
|
+
'redBright',
|
|
179
|
+
'greenBright',
|
|
180
|
+
'yellowBright',
|
|
181
|
+
'blueBright',
|
|
182
|
+
'magentaBright',
|
|
183
|
+
'cyanBright',
|
|
184
|
+
'whiteBright'
|
|
185
|
+
];
|
|
186
|
+
const color = colors[hash % colors.length];
|
|
187
|
+
|
|
188
|
+
return `<PublicKey ${printControlCode(inspect.colors[color]![0])}${this.truncate()}${printControlCode(inspect.colors.reset![0])}>`;
|
|
123
189
|
}
|
|
124
190
|
|
|
125
191
|
/**
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2020 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import debug from 'debug';
|
|
6
|
+
|
|
7
|
+
import { PublicKey } from './public-key';
|
|
8
|
+
import { Timeframe } from './timeframe';
|
|
9
|
+
|
|
10
|
+
const log = debug('dxos:protocols:timeframe:test');
|
|
11
|
+
|
|
12
|
+
describe('spacetime', () => {
|
|
13
|
+
test('constructors', () => {
|
|
14
|
+
const feedKey = PublicKey.random();
|
|
15
|
+
|
|
16
|
+
const tf1 = new Timeframe([[feedKey, 1]]);
|
|
17
|
+
log(tf1.toString());
|
|
18
|
+
expect(tf1).toBeTruthy();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('merge/subtract', () => {
|
|
22
|
+
const feedKey1 = PublicKey.random();
|
|
23
|
+
const feedKey2 = PublicKey.random();
|
|
24
|
+
const feedKey3 = PublicKey.random();
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
// Merge.
|
|
28
|
+
const tf1 = new Timeframe();
|
|
29
|
+
const tf2 = new Timeframe([[feedKey1, 2], [feedKey2, 1]]);
|
|
30
|
+
const tf3 = Timeframe.merge(tf1, tf2);
|
|
31
|
+
expect(tf3.frames()).toHaveLength(2);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
// Merge (no change).
|
|
36
|
+
const tf1 = new Timeframe([[feedKey1, 1], [feedKey2, 1]]);
|
|
37
|
+
const tf2 = new Timeframe([[feedKey1, 2], [feedKey3, 1]]);
|
|
38
|
+
const tf3 = Timeframe.merge(tf1, tf2);
|
|
39
|
+
expect(tf3.frames()).toHaveLength(3);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
// Merge (no change).
|
|
44
|
+
const tf1 = new Timeframe([[feedKey1, 1]]);
|
|
45
|
+
const tf2 = new Timeframe([[feedKey1, 3]]);
|
|
46
|
+
const tf3 = new Timeframe([[feedKey1, 2]]);
|
|
47
|
+
const tf4 = Timeframe.merge(tf1, tf2, tf3);
|
|
48
|
+
log(tf4.toString());
|
|
49
|
+
expect(tf4.frames()).toHaveLength(1);
|
|
50
|
+
expect(tf4.get(feedKey1)).toBe(3);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
// Remove keys.
|
|
55
|
+
const tf1 = new Timeframe([[feedKey1, 1], [feedKey2, 2]]);
|
|
56
|
+
const tf2 = tf1.withoutKeys([feedKey1, feedKey3]);
|
|
57
|
+
expect(tf2.frames()).toHaveLength(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('dependencies', () => {
|
|
62
|
+
const feedKey1 = PublicKey.random();
|
|
63
|
+
const feedKey2 = PublicKey.random();
|
|
64
|
+
const feedKey3 = PublicKey.random();
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
const tf1 = new Timeframe();
|
|
68
|
+
const tf2 = new Timeframe();
|
|
69
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
70
|
+
log(tf3.toString());
|
|
71
|
+
expect(tf3.frames()).toHaveLength(0);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
const tf1 = new Timeframe();
|
|
76
|
+
const tf2 = new Timeframe([[feedKey1, 10], [feedKey2, 11]]);
|
|
77
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
78
|
+
log(tf3.toString());
|
|
79
|
+
expect(tf3.frames()).toHaveLength(0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
const tf1 = new Timeframe([[feedKey1, 10], [feedKey2, 10]]);
|
|
84
|
+
const tf2 = new Timeframe();
|
|
85
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
86
|
+
log(tf3.toString());
|
|
87
|
+
expect(tf3.frames()).toHaveLength(2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// TODO(burdon): Test 0.
|
|
91
|
+
{
|
|
92
|
+
const tf1 = new Timeframe([[feedKey1, 0]]);
|
|
93
|
+
const tf2 = new Timeframe([[feedKey1, 0]]);
|
|
94
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
95
|
+
log(tf3.toString());
|
|
96
|
+
expect(tf3.frames()).toHaveLength(0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
const tf1 = new Timeframe([[feedKey1, 1]]);
|
|
101
|
+
const tf2 = new Timeframe([[feedKey1, 1]]);
|
|
102
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
103
|
+
log(tf1.toString());
|
|
104
|
+
log(tf2.toString());
|
|
105
|
+
log(tf3.toString());
|
|
106
|
+
expect(tf3.frames()).toHaveLength(0);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
{
|
|
110
|
+
const tf1 = new Timeframe([[feedKey1, 10], [feedKey2, 10]]);
|
|
111
|
+
const tf2 = new Timeframe([[feedKey1, 10], [feedKey2, 11]]);
|
|
112
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
113
|
+
log(tf3.toString());
|
|
114
|
+
expect(tf3.frames()).toHaveLength(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
{
|
|
118
|
+
const tf1 = new Timeframe([[feedKey1, 10], [feedKey2, 10], [feedKey3, 10]]);
|
|
119
|
+
const tf2 = new Timeframe([[feedKey1, 10], [feedKey2, 9]]);
|
|
120
|
+
const tf3 = Timeframe.dependencies(tf1, tf2);
|
|
121
|
+
log(tf3.toString());
|
|
122
|
+
expect(tf3.frames()).toHaveLength(2);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
package/src/timeframe.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2020 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { inspect } from 'node:util';
|
|
6
|
+
|
|
7
|
+
import { PublicKey } from './public-key';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A mapping of feed key to a sequence number on that feed.
|
|
11
|
+
* Describes how many messages have been processed.
|
|
12
|
+
*/
|
|
13
|
+
export class Timeframe {
|
|
14
|
+
// Cannot use ComplexMap because @dxos/util depends on @dxos/protocols for PublicKey.
|
|
15
|
+
private readonly _keys = new Map<string, PublicKey>();
|
|
16
|
+
private readonly _frames = new Map<string, number>();
|
|
17
|
+
|
|
18
|
+
constructor (frames: [PublicKey, number][] = []) {
|
|
19
|
+
for (const [key, seq] of frames) {
|
|
20
|
+
this.set(key, seq);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get (key: PublicKey) {
|
|
25
|
+
const keyString = key.toString();
|
|
26
|
+
return this._frames.get(keyString);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
set (key: PublicKey, value: number) {
|
|
30
|
+
const keyString = key.toString();
|
|
31
|
+
this._frames.set(keyString, value);
|
|
32
|
+
this._keys.set(keyString, key);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// TODO(burdon): Change to getter.
|
|
36
|
+
frames (): [PublicKey, number][] {
|
|
37
|
+
return Array.from(this._frames.entries())
|
|
38
|
+
.map(([keyString, value]): [PublicKey, number] | undefined => {
|
|
39
|
+
const key = this._keys.get(keyString);
|
|
40
|
+
if (!key) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return [key, value];
|
|
45
|
+
})
|
|
46
|
+
.filter((frame): frame is [PublicKey, number] => !!frame);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// TODO(burdon): Change to getter.
|
|
50
|
+
size () {
|
|
51
|
+
return this._frames.size;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// TODO(burdon): Change to getter (empty).
|
|
55
|
+
isEmpty () {
|
|
56
|
+
return this.size() === 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns a new timeframe with specified keys removed.
|
|
61
|
+
* @param keys
|
|
62
|
+
*/
|
|
63
|
+
withoutKeys (keys: PublicKey[]): Timeframe {
|
|
64
|
+
return new Timeframe(this.frames().filter(([frameKey]) => keys.every(key =>
|
|
65
|
+
Buffer.compare(key.asBuffer(), frameKey.asBuffer()) !== 0)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns a total amount of messages represented by this timeframe.
|
|
70
|
+
*/
|
|
71
|
+
totalMessages (): number {
|
|
72
|
+
return Array.from(this._frames.values()).reduce((acc, seq) => acc + seq + 1, 0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
toJSON () {
|
|
76
|
+
return this.frames().reduce((frames: Record<string, number>, [key, seq]) => {
|
|
77
|
+
frames[key.truncate()] = seq;
|
|
78
|
+
return frames;
|
|
79
|
+
}, {});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
toString () {
|
|
83
|
+
return `(${this.frames().map(([key, seq]) => `${key.truncate()} => ${seq}`).join(', ')})`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Used by NodeJS to get textual representation of this object when it's printed with a `console.log` statement.
|
|
88
|
+
*/
|
|
89
|
+
[inspect.custom] () {
|
|
90
|
+
return `Timeframe${this.toString()}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Merges the values, updating the highest sequence numbers.
|
|
95
|
+
* @param timeframes
|
|
96
|
+
*/
|
|
97
|
+
static merge (...timeframes: Timeframe[]): Timeframe {
|
|
98
|
+
const result = new Timeframe();
|
|
99
|
+
for (const timeframe of timeframes) {
|
|
100
|
+
for (const [key, seq] of timeframe.frames()) {
|
|
101
|
+
const current = result.get(key);
|
|
102
|
+
if (current === undefined || seq > current) {
|
|
103
|
+
result.set(key, seq);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Compares two timeframes and returns an array of frames from the first timeframe where the sequence number
|
|
113
|
+
* is greater than the associated sequence number from the second timeframe.
|
|
114
|
+
*
|
|
115
|
+
* @param tf1
|
|
116
|
+
* @param tf2
|
|
117
|
+
*/
|
|
118
|
+
static dependencies (
|
|
119
|
+
tf1: Timeframe, tf2: Timeframe
|
|
120
|
+
): Timeframe {
|
|
121
|
+
const result = new Timeframe();
|
|
122
|
+
for (const [key, seq] of tf1.frames()) {
|
|
123
|
+
const otherSeq = tf2.get(key);
|
|
124
|
+
if (otherSeq === undefined || otherSeq < seq) {
|
|
125
|
+
result.set(key, seq);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const timeframeSubstitutions = {
|
|
134
|
+
'dxos.echo.timeframe.TimeframeVector': {
|
|
135
|
+
encode: (timeframe: Timeframe) => ({
|
|
136
|
+
frames: timeframe.frames().map(([feedKey, seq]) => ({ feedKey: feedKey.asUint8Array(), seq }))
|
|
137
|
+
}),
|
|
138
|
+
decode: (vector: any) => new Timeframe(
|
|
139
|
+
(vector.frames ?? [])
|
|
140
|
+
.filter((frame: any) => frame.feedKey != null && frame.seq != null)
|
|
141
|
+
.map((frame: any) => [PublicKey.from(new Uint8Array(frame.feedKey)), frame.seq])
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
};
|