@dxos/teleport-extension-object-sync 0.8.4-main.ead640a → 0.8.4-main.f466a3d56e
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 +102 -5
- package/dist/lib/{browser → neutral}/index.mjs +105 -293
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/meta.json +1 -1
- package/dist/types/src/blob-store.d.ts.map +1 -1
- package/dist/types/src/blob-sync-extension.d.ts +2 -2
- package/dist/types/src/blob-sync-extension.d.ts.map +1 -1
- package/dist/types/src/blob-sync.d.ts +2 -2
- package/dist/types/src/blob-sync.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/src/blob-sync-extension.ts +2 -2
- package/src/blob-sync.node.test.ts +0 -1
- package/src/blob-sync.ts +2 -2
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -682
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
package/LICENSE
CHANGED
|
@@ -1,8 +1,105 @@
|
|
|
1
|
-
|
|
2
|
-
Copyright (c) 2022 DXOS
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
## Abbreviation
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 DXOS
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
|
@@ -9,57 +9,97 @@ import { RpcClosedError } from "@dxos/protocols";
|
|
|
9
9
|
import { schema } from "@dxos/protocols/proto";
|
|
10
10
|
import { RpcExtension } from "@dxos/teleport";
|
|
11
11
|
import { BitField } from "@dxos/util";
|
|
12
|
-
|
|
13
|
-
if (key in obj) {
|
|
14
|
-
Object.defineProperty(obj, key, {
|
|
15
|
-
value,
|
|
16
|
-
enumerable: true,
|
|
17
|
-
configurable: true,
|
|
18
|
-
writable: true
|
|
19
|
-
});
|
|
20
|
-
} else {
|
|
21
|
-
obj[key] = value;
|
|
22
|
-
}
|
|
23
|
-
return obj;
|
|
24
|
-
}
|
|
12
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-sync-extension.ts";
|
|
25
13
|
function _ts_decorate(decorators, target, key, desc) {
|
|
26
14
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
27
15
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
28
16
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
29
17
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
30
18
|
}
|
|
31
|
-
var
|
|
32
|
-
var MIN_WANT_LIST_UPDATE_INTERVAL = false ? 5 : 500;
|
|
19
|
+
var MIN_WANT_LIST_UPDATE_INTERVAL = process.env.NODE_ENV === "test" ? 5 : 500;
|
|
33
20
|
var MAX_CONCURRENT_UPLOADS = 20;
|
|
34
21
|
var BlobSyncExtension = class extends RpcExtension {
|
|
22
|
+
_params;
|
|
23
|
+
_ctx = new Context({
|
|
24
|
+
onError: (err) => log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 26, S: this })
|
|
25
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 25 });
|
|
26
|
+
_lastWantListUpdate = 0;
|
|
27
|
+
_localWantList = {
|
|
28
|
+
blobs: []
|
|
29
|
+
};
|
|
30
|
+
_updateWantList = new DeferredTask(this._ctx, async () => {
|
|
31
|
+
if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {
|
|
32
|
+
await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());
|
|
33
|
+
if (this._ctx.disposed) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
log("want", {
|
|
38
|
+
list: this._localWantList
|
|
39
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 40, S: this });
|
|
40
|
+
await this.rpc.BlobSyncService.want(this._localWantList);
|
|
41
|
+
this._lastWantListUpdate = Date.now();
|
|
42
|
+
});
|
|
43
|
+
_currentUploads = 0;
|
|
44
|
+
_upload = new DeferredTask(this._ctx, async () => {
|
|
45
|
+
if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);
|
|
49
|
+
if (!blobChunks) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (const blobChunk of blobChunks) {
|
|
53
|
+
if (this._ctx.disposed) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
this._currentUploads++;
|
|
57
|
+
this.push(blobChunk).catch((err) => {
|
|
58
|
+
if (err instanceof RpcClosedError) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
log.warn("push failed", {
|
|
62
|
+
err
|
|
63
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 64, S: this });
|
|
64
|
+
}).finally(() => {
|
|
65
|
+
this._currentUploads--;
|
|
66
|
+
this.reconcileUploads();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Set of id's remote peer wants.
|
|
72
|
+
*/
|
|
73
|
+
remoteWantList = {
|
|
74
|
+
blobs: []
|
|
75
|
+
};
|
|
76
|
+
constructor(_params) {
|
|
77
|
+
super({
|
|
78
|
+
exposed: {
|
|
79
|
+
BlobSyncService: schema.getService("dxos.mesh.teleport.blobsync.BlobSyncService")
|
|
80
|
+
},
|
|
81
|
+
requested: {
|
|
82
|
+
BlobSyncService: schema.getService("dxos.mesh.teleport.blobsync.BlobSyncService")
|
|
83
|
+
},
|
|
84
|
+
timeout: 2e4,
|
|
85
|
+
encodingOptions: {
|
|
86
|
+
preserveAny: true
|
|
87
|
+
}
|
|
88
|
+
}), this._params = _params;
|
|
89
|
+
}
|
|
35
90
|
async onOpen(context) {
|
|
36
|
-
log("open", void 0, {
|
|
37
|
-
F: __dxlog_file,
|
|
38
|
-
L: 108,
|
|
39
|
-
S: this,
|
|
40
|
-
C: (f, a) => f(...a)
|
|
41
|
-
});
|
|
91
|
+
log("open", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 93, S: this });
|
|
42
92
|
await super.onOpen(context);
|
|
43
93
|
await this._params.onOpen();
|
|
44
94
|
}
|
|
45
95
|
async onClose(err) {
|
|
46
|
-
log("close", void 0, {
|
|
47
|
-
F: __dxlog_file,
|
|
48
|
-
L: 114,
|
|
49
|
-
S: this,
|
|
50
|
-
C: (f, a) => f(...a)
|
|
51
|
-
});
|
|
96
|
+
log("close", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 98, S: this });
|
|
52
97
|
await this._ctx.dispose();
|
|
53
98
|
await this._params.onClose();
|
|
54
99
|
await super.onClose(err);
|
|
55
100
|
}
|
|
56
101
|
async onAbort(err) {
|
|
57
|
-
log("abort", void 0, {
|
|
58
|
-
F: __dxlog_file,
|
|
59
|
-
L: 121,
|
|
60
|
-
S: this,
|
|
61
|
-
C: (f, a) => f(...a)
|
|
62
|
-
});
|
|
102
|
+
log("abort", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 104, S: this });
|
|
63
103
|
await this._ctx.dispose();
|
|
64
104
|
await this._params.onAbort();
|
|
65
105
|
await super.onAbort(err);
|
|
@@ -70,24 +110,14 @@ var BlobSyncExtension = class extends RpcExtension {
|
|
|
70
110
|
want: async (wantList) => {
|
|
71
111
|
log("remote want", {
|
|
72
112
|
remoteWantList: wantList
|
|
73
|
-
}, {
|
|
74
|
-
F: __dxlog_file,
|
|
75
|
-
L: 131,
|
|
76
|
-
S: this,
|
|
77
|
-
C: (f, a) => f(...a)
|
|
78
|
-
});
|
|
113
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 113, S: this });
|
|
79
114
|
this.remoteWantList = wantList;
|
|
80
115
|
this.reconcileUploads();
|
|
81
116
|
},
|
|
82
117
|
push: async (data) => {
|
|
83
118
|
log("received", {
|
|
84
119
|
data
|
|
85
|
-
}, {
|
|
86
|
-
F: __dxlog_file,
|
|
87
|
-
L: 136,
|
|
88
|
-
S: this,
|
|
89
|
-
C: (f, a) => f(...a)
|
|
90
|
-
});
|
|
120
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 120, S: this });
|
|
91
121
|
await this._params.onPush(data);
|
|
92
122
|
}
|
|
93
123
|
}
|
|
@@ -99,12 +129,7 @@ var BlobSyncExtension = class extends RpcExtension {
|
|
|
99
129
|
}
|
|
100
130
|
log("push", {
|
|
101
131
|
data
|
|
102
|
-
}, {
|
|
103
|
-
F: __dxlog_file,
|
|
104
|
-
L: 148,
|
|
105
|
-
S: this,
|
|
106
|
-
C: (f, a) => f(...a)
|
|
107
|
-
});
|
|
132
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 132, S: this });
|
|
108
133
|
await this.rpc.BlobSyncService.push(data);
|
|
109
134
|
}
|
|
110
135
|
updateWantList(wantList) {
|
|
@@ -136,43 +161,14 @@ var BlobSyncExtension = class extends RpcExtension {
|
|
|
136
161
|
if (!meta) {
|
|
137
162
|
continue;
|
|
138
163
|
}
|
|
139
|
-
invariant(meta.bitfield, void 0, {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
S: this,
|
|
143
|
-
A: [
|
|
144
|
-
"meta.bitfield",
|
|
145
|
-
""
|
|
146
|
-
]
|
|
147
|
-
});
|
|
148
|
-
invariant(meta.chunkSize, void 0, {
|
|
149
|
-
F: __dxlog_file,
|
|
150
|
-
L: 188,
|
|
151
|
-
S: this,
|
|
152
|
-
A: [
|
|
153
|
-
"meta.chunkSize",
|
|
154
|
-
""
|
|
155
|
-
]
|
|
156
|
-
});
|
|
157
|
-
invariant(meta.length, void 0, {
|
|
158
|
-
F: __dxlog_file,
|
|
159
|
-
L: 189,
|
|
160
|
-
S: this,
|
|
161
|
-
A: [
|
|
162
|
-
"meta.length",
|
|
163
|
-
""
|
|
164
|
-
]
|
|
165
|
-
});
|
|
164
|
+
invariant(meta.bitfield, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 166, S: this, A: ["meta.bitfield", ""] });
|
|
165
|
+
invariant(meta.chunkSize, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 167, S: this, A: ["meta.chunkSize", ""] });
|
|
166
|
+
invariant(meta.length, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 168, S: this, A: ["meta.length", ""] });
|
|
166
167
|
if (header.chunkSize && header.chunkSize !== meta.chunkSize) {
|
|
167
168
|
log.warn("Invalid chunk size", {
|
|
168
169
|
header,
|
|
169
170
|
meta
|
|
170
|
-
}, {
|
|
171
|
-
F: __dxlog_file,
|
|
172
|
-
L: 192,
|
|
173
|
-
S: this,
|
|
174
|
-
C: (f, a) => f(...a)
|
|
175
|
-
});
|
|
171
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 170, S: this });
|
|
176
172
|
continue;
|
|
177
173
|
}
|
|
178
174
|
const requestBitfield = header.bitfield ?? BitField.ones(meta.length / meta.chunkSize);
|
|
@@ -197,84 +193,6 @@ var BlobSyncExtension = class extends RpcExtension {
|
|
|
197
193
|
}
|
|
198
194
|
return chunks;
|
|
199
195
|
}
|
|
200
|
-
constructor(_params) {
|
|
201
|
-
super({
|
|
202
|
-
exposed: {
|
|
203
|
-
BlobSyncService: schema.getService("dxos.mesh.teleport.blobsync.BlobSyncService")
|
|
204
|
-
},
|
|
205
|
-
requested: {
|
|
206
|
-
BlobSyncService: schema.getService("dxos.mesh.teleport.blobsync.BlobSyncService")
|
|
207
|
-
},
|
|
208
|
-
timeout: 2e4,
|
|
209
|
-
encodingOptions: {
|
|
210
|
-
preserveAny: true
|
|
211
|
-
}
|
|
212
|
-
}), _define_property(this, "_params", void 0), _define_property(this, "_ctx", void 0), _define_property(this, "_lastWantListUpdate", void 0), _define_property(this, "_localWantList", void 0), _define_property(this, "_updateWantList", void 0), _define_property(this, "_currentUploads", void 0), _define_property(this, "_upload", void 0), /**
|
|
213
|
-
* Set of id's remote peer wants.
|
|
214
|
-
*/
|
|
215
|
-
_define_property(this, "remoteWantList", void 0), this._params = _params, this._ctx = new Context({
|
|
216
|
-
onError: (err) => log.catch(err, void 0, {
|
|
217
|
-
F: __dxlog_file,
|
|
218
|
-
L: 35,
|
|
219
|
-
S: this,
|
|
220
|
-
C: (f, a) => f(...a)
|
|
221
|
-
})
|
|
222
|
-
}, {
|
|
223
|
-
F: __dxlog_file,
|
|
224
|
-
L: 35
|
|
225
|
-
}), this._lastWantListUpdate = 0, this._localWantList = {
|
|
226
|
-
blobs: []
|
|
227
|
-
}, this._updateWantList = new DeferredTask(this._ctx, async () => {
|
|
228
|
-
if (this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL > Date.now()) {
|
|
229
|
-
await sleep(this._lastWantListUpdate + MIN_WANT_LIST_UPDATE_INTERVAL - Date.now());
|
|
230
|
-
if (this._ctx.disposed) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
log("want", {
|
|
235
|
-
list: this._localWantList
|
|
236
|
-
}, {
|
|
237
|
-
F: __dxlog_file,
|
|
238
|
-
L: 49,
|
|
239
|
-
S: this,
|
|
240
|
-
C: (f, a) => f(...a)
|
|
241
|
-
});
|
|
242
|
-
await this.rpc.BlobSyncService.want(this._localWantList);
|
|
243
|
-
this._lastWantListUpdate = Date.now();
|
|
244
|
-
}), this._currentUploads = 0, this._upload = new DeferredTask(this._ctx, async () => {
|
|
245
|
-
if (this._currentUploads >= MAX_CONCURRENT_UPLOADS) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
const blobChunks = await this._pickBlobChunks(MAX_CONCURRENT_UPLOADS - this._currentUploads);
|
|
249
|
-
if (!blobChunks) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
for (const blobChunk of blobChunks) {
|
|
253
|
-
if (this._ctx.disposed) {
|
|
254
|
-
break;
|
|
255
|
-
}
|
|
256
|
-
this._currentUploads++;
|
|
257
|
-
this.push(blobChunk).catch((err) => {
|
|
258
|
-
if (err instanceof RpcClosedError) {
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
log.warn("push failed", {
|
|
262
|
-
err
|
|
263
|
-
}, {
|
|
264
|
-
F: __dxlog_file,
|
|
265
|
-
L: 76,
|
|
266
|
-
S: this,
|
|
267
|
-
C: (f, a) => f(...a)
|
|
268
|
-
});
|
|
269
|
-
}).finally(() => {
|
|
270
|
-
this._currentUploads--;
|
|
271
|
-
this.reconcileUploads();
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
}), this.remoteWantList = {
|
|
275
|
-
blobs: []
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
196
|
};
|
|
279
197
|
_ts_decorate([
|
|
280
198
|
synchronized
|
|
@@ -288,27 +206,22 @@ import { PublicKey } from "@dxos/keys";
|
|
|
288
206
|
import { log as log2 } from "@dxos/log";
|
|
289
207
|
import { BlobMeta } from "@dxos/protocols/proto/dxos/echo/blob";
|
|
290
208
|
import { BitField as BitField2, ComplexMap } from "@dxos/util";
|
|
291
|
-
|
|
292
|
-
if (key in obj) {
|
|
293
|
-
Object.defineProperty(obj, key, {
|
|
294
|
-
value,
|
|
295
|
-
enumerable: true,
|
|
296
|
-
configurable: true,
|
|
297
|
-
writable: true
|
|
298
|
-
});
|
|
299
|
-
} else {
|
|
300
|
-
obj[key] = value;
|
|
301
|
-
}
|
|
302
|
-
return obj;
|
|
303
|
-
}
|
|
209
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts";
|
|
304
210
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
305
211
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
306
212
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
307
213
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
308
214
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
309
215
|
}
|
|
310
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-sync.ts";
|
|
311
216
|
var BlobSync = class {
|
|
217
|
+
_params;
|
|
218
|
+
_ctx = new Context2(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 20 });
|
|
219
|
+
_mutex = new Mutex();
|
|
220
|
+
_downloadRequests = new ComplexMap((key) => PublicKey.from(key).toHex());
|
|
221
|
+
_extensions = /* @__PURE__ */ new Set();
|
|
222
|
+
constructor(_params) {
|
|
223
|
+
this._params = _params;
|
|
224
|
+
}
|
|
312
225
|
async open() {
|
|
313
226
|
}
|
|
314
227
|
async close() {
|
|
@@ -322,12 +235,7 @@ var BlobSync = class {
|
|
|
322
235
|
async download(ctx, id) {
|
|
323
236
|
log2("download", {
|
|
324
237
|
id
|
|
325
|
-
}, {
|
|
326
|
-
F: __dxlog_file2,
|
|
327
|
-
L: 53,
|
|
328
|
-
S: this,
|
|
329
|
-
C: (f, a) => f(...a)
|
|
330
|
-
});
|
|
238
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 36, S: this });
|
|
331
239
|
const request = await this._mutex.executeSynchronized(async () => {
|
|
332
240
|
const existingRequest = this._downloadRequests.get(id);
|
|
333
241
|
if (existingRequest) {
|
|
@@ -368,31 +276,16 @@ var BlobSync = class {
|
|
|
368
276
|
const extension = new BlobSyncExtension({
|
|
369
277
|
blobStore: this._params.blobStore,
|
|
370
278
|
onOpen: async () => {
|
|
371
|
-
log2("extension opened", void 0, {
|
|
372
|
-
F: __dxlog_file2,
|
|
373
|
-
L: 105,
|
|
374
|
-
S: this,
|
|
375
|
-
C: (f, a) => f(...a)
|
|
376
|
-
});
|
|
279
|
+
log2("extension opened", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 81, S: this });
|
|
377
280
|
this._extensions.add(extension);
|
|
378
281
|
extension.updateWantList(this._getWantList());
|
|
379
282
|
},
|
|
380
283
|
onClose: async () => {
|
|
381
|
-
log2("extension closed", void 0, {
|
|
382
|
-
F: __dxlog_file2,
|
|
383
|
-
L: 110,
|
|
384
|
-
S: this,
|
|
385
|
-
C: (f, a) => f(...a)
|
|
386
|
-
});
|
|
284
|
+
log2("extension closed", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 86, S: this });
|
|
387
285
|
this._extensions.delete(extension);
|
|
388
286
|
},
|
|
389
287
|
onAbort: async () => {
|
|
390
|
-
log2("extension aborted", void 0, {
|
|
391
|
-
F: __dxlog_file2,
|
|
392
|
-
L: 114,
|
|
393
|
-
S: this,
|
|
394
|
-
C: (f, a) => f(...a)
|
|
395
|
-
});
|
|
288
|
+
log2("extension aborted", void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 90, S: this });
|
|
396
289
|
this._extensions.delete(extension);
|
|
397
290
|
},
|
|
398
291
|
onPush: async (blobChunk) => {
|
|
@@ -401,26 +294,13 @@ var BlobSync = class {
|
|
|
401
294
|
}
|
|
402
295
|
log2("received", {
|
|
403
296
|
blobChunk
|
|
404
|
-
}, {
|
|
405
|
-
F: __dxlog_file2,
|
|
406
|
-
L: 121,
|
|
407
|
-
S: this,
|
|
408
|
-
C: (f, a) => f(...a)
|
|
409
|
-
});
|
|
297
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 97, S: this });
|
|
410
298
|
const meta = await this._params.blobStore.setChunk(blobChunk);
|
|
411
299
|
if (meta.state === BlobMeta.State.FULLY_PRESENT) {
|
|
412
300
|
this._downloadRequests.get(blobChunk.id)?.trigger.wake();
|
|
413
301
|
this._downloadRequests.delete(blobChunk.id);
|
|
414
302
|
} else {
|
|
415
|
-
invariant2(meta.bitfield, void 0, {
|
|
416
|
-
F: __dxlog_file2,
|
|
417
|
-
L: 127,
|
|
418
|
-
S: this,
|
|
419
|
-
A: [
|
|
420
|
-
"meta.bitfield",
|
|
421
|
-
""
|
|
422
|
-
]
|
|
423
|
-
});
|
|
303
|
+
invariant2(meta.bitfield, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 105, S: this, A: ["meta.bitfield", ""] });
|
|
424
304
|
this._downloadRequests.get(blobChunk.id).want.bitfield = BitField2.invert(meta.bitfield);
|
|
425
305
|
}
|
|
426
306
|
this._updateExtensionsWantList();
|
|
@@ -450,21 +330,6 @@ var BlobSync = class {
|
|
|
450
330
|
extension.updateWantList(this._getWantList());
|
|
451
331
|
}
|
|
452
332
|
}
|
|
453
|
-
constructor(_params) {
|
|
454
|
-
_define_property2(this, "_params", void 0);
|
|
455
|
-
_define_property2(this, "_ctx", void 0);
|
|
456
|
-
_define_property2(this, "_mutex", void 0);
|
|
457
|
-
_define_property2(this, "_downloadRequests", void 0);
|
|
458
|
-
_define_property2(this, "_extensions", void 0);
|
|
459
|
-
this._params = _params;
|
|
460
|
-
this._ctx = new Context2(void 0, {
|
|
461
|
-
F: __dxlog_file2,
|
|
462
|
-
L: 30
|
|
463
|
-
});
|
|
464
|
-
this._mutex = new Mutex();
|
|
465
|
-
this._downloadRequests = new ComplexMap((key) => PublicKey.from(key).toHex());
|
|
466
|
-
this._extensions = /* @__PURE__ */ new Set();
|
|
467
|
-
}
|
|
468
333
|
};
|
|
469
334
|
BlobSync = _ts_decorate2([
|
|
470
335
|
trackLeaks("open", "close")
|
|
@@ -479,29 +344,20 @@ import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
|
479
344
|
import { schema as schema2 } from "@dxos/protocols/proto";
|
|
480
345
|
import { BlobMeta as BlobMeta2 } from "@dxos/protocols/proto/dxos/echo/blob";
|
|
481
346
|
import { BitField as BitField3, arrayToBuffer } from "@dxos/util";
|
|
482
|
-
|
|
483
|
-
if (key in obj) {
|
|
484
|
-
Object.defineProperty(obj, key, {
|
|
485
|
-
value,
|
|
486
|
-
enumerable: true,
|
|
487
|
-
configurable: true,
|
|
488
|
-
writable: true
|
|
489
|
-
});
|
|
490
|
-
} else {
|
|
491
|
-
obj[key] = value;
|
|
492
|
-
}
|
|
493
|
-
return obj;
|
|
494
|
-
}
|
|
347
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts";
|
|
495
348
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
496
349
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
497
350
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
498
351
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
499
352
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
500
353
|
}
|
|
501
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/mesh/teleport-extension-object-sync/src/blob-store.ts";
|
|
502
354
|
var DEFAULT_CHUNK_SIZE = 4096;
|
|
503
355
|
var BlobMetaCodec = schema2.getCodecForType("dxos.echo.blob.BlobMeta");
|
|
504
356
|
var BlobStore = class {
|
|
357
|
+
_directory;
|
|
358
|
+
constructor(_directory) {
|
|
359
|
+
this._directory = _directory;
|
|
360
|
+
}
|
|
505
361
|
async getMeta(id) {
|
|
506
362
|
return this._getMeta(id);
|
|
507
363
|
}
|
|
@@ -525,24 +381,8 @@ var BlobStore = class {
|
|
|
525
381
|
}
|
|
526
382
|
const beginChunk = Math.floor(offset / metadata.chunkSize);
|
|
527
383
|
const endChunk = Math.ceil((offset + length) / metadata.chunkSize);
|
|
528
|
-
invariant3(metadata.bitfield, "Bitfield not present", {
|
|
529
|
-
|
|
530
|
-
L: 61,
|
|
531
|
-
S: this,
|
|
532
|
-
A: [
|
|
533
|
-
"metadata.bitfield",
|
|
534
|
-
"'Bitfield not present'"
|
|
535
|
-
]
|
|
536
|
-
});
|
|
537
|
-
invariant3(metadata.bitfield.length * 8 >= endChunk, "Invalid bitfield length", {
|
|
538
|
-
F: __dxlog_file3,
|
|
539
|
-
L: 62,
|
|
540
|
-
S: this,
|
|
541
|
-
A: [
|
|
542
|
-
"metadata.bitfield.length * 8 >= endChunk",
|
|
543
|
-
"'Invalid bitfield length'"
|
|
544
|
-
]
|
|
545
|
-
});
|
|
384
|
+
invariant3(metadata.bitfield, "Bitfield not present", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 47, S: this, A: ["metadata.bitfield", "'Bitfield not present'"] });
|
|
385
|
+
invariant3(metadata.bitfield.length * 8 >= endChunk, "Invalid bitfield length", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 48, S: this, A: ["metadata.bitfield.length * 8 >= endChunk", "'Invalid bitfield length'"] });
|
|
546
386
|
const present = BitField3.count(metadata.bitfield, beginChunk, endChunk) === endChunk - beginChunk;
|
|
547
387
|
if (!present) {
|
|
548
388
|
throw new Error("Blob not available");
|
|
@@ -582,15 +422,7 @@ var BlobStore = class {
|
|
|
582
422
|
async setChunk(chunk) {
|
|
583
423
|
let meta = await this._getMeta(chunk.id);
|
|
584
424
|
if (!meta) {
|
|
585
|
-
invariant3(chunk.totalLength, "totalLength is not present", {
|
|
586
|
-
F: __dxlog_file3,
|
|
587
|
-
L: 124,
|
|
588
|
-
S: this,
|
|
589
|
-
A: [
|
|
590
|
-
"chunk.totalLength",
|
|
591
|
-
"'totalLength is not present'"
|
|
592
|
-
]
|
|
593
|
-
});
|
|
425
|
+
invariant3(chunk.totalLength, "totalLength is not present", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 95, S: this, A: ["chunk.totalLength", "'totalLength is not present'"] });
|
|
594
426
|
meta = {
|
|
595
427
|
id: chunk.id,
|
|
596
428
|
state: BlobMeta2.State.PARTIALLY_PRESENT,
|
|
@@ -603,24 +435,8 @@ var BlobStore = class {
|
|
|
603
435
|
if (chunk.chunkSize && chunk.chunkSize !== meta.chunkSize) {
|
|
604
436
|
throw new Error("Invalid chunk size");
|
|
605
437
|
}
|
|
606
|
-
invariant3(meta.bitfield, "Bitfield not present", {
|
|
607
|
-
|
|
608
|
-
L: 139,
|
|
609
|
-
S: this,
|
|
610
|
-
A: [
|
|
611
|
-
"meta.bitfield",
|
|
612
|
-
"'Bitfield not present'"
|
|
613
|
-
]
|
|
614
|
-
});
|
|
615
|
-
invariant3(chunk.chunkOffset !== void 0, "chunkOffset is not present", {
|
|
616
|
-
F: __dxlog_file3,
|
|
617
|
-
L: 140,
|
|
618
|
-
S: this,
|
|
619
|
-
A: [
|
|
620
|
-
"chunk.chunkOffset !== undefined",
|
|
621
|
-
"'chunkOffset is not present'"
|
|
622
|
-
]
|
|
623
|
-
});
|
|
438
|
+
invariant3(meta.bitfield, "Bitfield not present", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 108, S: this, A: ["meta.bitfield", "'Bitfield not present'"] });
|
|
439
|
+
invariant3(chunk.chunkOffset !== void 0, "chunkOffset is not present", { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 109, S: this, A: ["chunk.chunkOffset !== undefined", "'chunkOffset is not present'"] });
|
|
624
440
|
await this._getDataFile(chunk.id).write(chunk.chunkOffset, arrayToBuffer(chunk.payload));
|
|
625
441
|
BitField3.set(meta.bitfield, Math.floor(chunk.chunkOffset / meta.chunkSize), true);
|
|
626
442
|
if (BitField3.count(meta.bitfield, 0, meta.length) * meta.chunkSize >= meta.length) {
|
|
@@ -653,10 +469,6 @@ var BlobStore = class {
|
|
|
653
469
|
_getDataFile(id) {
|
|
654
470
|
return this._directory.getOrCreateFile(path.join(arrayToBuffer(id).toString("hex"), "data"));
|
|
655
471
|
}
|
|
656
|
-
constructor(_directory) {
|
|
657
|
-
_define_property3(this, "_directory", void 0);
|
|
658
|
-
this._directory = _directory;
|
|
659
|
-
}
|
|
660
472
|
};
|
|
661
473
|
_ts_decorate3([
|
|
662
474
|
synchronized2
|