core-3nweb-client-lib 0.27.11 → 0.28.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.
@@ -45,6 +45,8 @@ declare namespace web3n.asmail {
45
45
  idOnDelivery?: string;
46
46
  err?: any;
47
47
  bytesSent: number;
48
+ // XXX
49
+ nonFstAttempt?: boolean;
48
50
  }
49
51
  };
50
52
  }
@@ -60,6 +62,12 @@ declare namespace web3n.asmail {
60
62
  * associated with particular delivery.
61
63
  */
62
64
  localMeta?: any;
65
+
66
+ retryRecipient?: {
67
+ numOfAttempts: number;
68
+ // XXX default client says "ASAP" => figgure it out
69
+ timeBetweenAttempts?: number;
70
+ };
63
71
  }
64
72
 
65
73
  interface DeliveryService {
@@ -232,6 +240,7 @@ declare namespace web3n.asmail {
232
240
  sender: string;
233
241
  establishedSenderKeyChain: boolean;
234
242
  attachments?: files.ReadonlyFS;
243
+ // XXX info if not from the first attempt
235
244
  }
236
245
 
237
246
  interface OutgoingMessage extends MsgStruct {
@@ -22,6 +22,7 @@ declare namespace web3n.files {
22
22
  type: 'file';
23
23
  code: string|undefined;
24
24
  path: string;
25
+ fsEtityType?: 'file' | 'link' | 'folder';
25
26
  }
26
27
 
27
28
  interface FileExceptionFlag {
@@ -99,6 +99,7 @@ class InboxOnServer {
99
99
  async removeMsgFromServerAndCache(msgId) {
100
100
  await Promise.all([
101
101
  this.cache.deleteMsg(msgId),
102
+ // XXX the following is suspicious, as it swallows other exceptions too
102
103
  this.msgReceiver.removeMsg(msgId).catch(() => { })
103
104
  ]);
104
105
  }
@@ -24,6 +24,8 @@ const buffer_utils_1 = require("../../../lib-common/buffer-utils");
24
24
  const fs_sync_utils_1 = require("../../../lib-client/fs-sync-utils");
25
25
  const rxjs_1 = require("rxjs");
26
26
  const operators_1 = require("rxjs/operators");
27
+ // XXX Use TableColumnsAndParams from lib-with-sql.
28
+ // And should we update here sqlite from that project?
27
29
  const indexTab = 'inbox_index';
28
30
  const column = {
29
31
  msgId: 'msg_id',
@@ -55,7 +55,7 @@ class OwnSendingParams extends file_based_json_1.JsonFileProc {
55
55
  };
56
56
  p.suggested.timestamp = Date.now();
57
57
  this.params.set(p.address, p);
58
- await this.persist();
58
+ await this.changesProc.startOrChain(() => this.persist());
59
59
  return p.suggested;
60
60
  };
61
61
  this.setAsInUse = async (address, invite) => {
@@ -22,7 +22,7 @@ const exceptions_1 = require("../../../lib-client/3nstorage/exceptions");
22
22
  const json_saving_1 = require("../common/json-saving");
23
23
  const obj_info_file_1 = require("../common/obj-info-file");
24
24
  const assert_1 = require("../../../lib-common/assert");
25
- const file_1 = require("../../../lib-common/exceptions/file");
25
+ const runtime_1 = require("../../../lib-common/exceptions/runtime");
26
26
  function makeVersions() {
27
27
  return {
28
28
  baseToDiff: {},
@@ -195,7 +195,10 @@ class ObjStatus {
195
195
  return;
196
196
  }
197
197
  else {
198
- throw (0, file_1.makeFileException)('concurrentUpdate', 'obj-status', `Upload is in progress`);
198
+ throw (0, runtime_1.makeRuntimeException)('file', {
199
+ path: (0, path_1.join)(this.objFolder, exports.STATUS_FILE_NAME),
200
+ fsEtityType: 'file', message: `Upload is in progress`
201
+ }, { concurrentUpdate: true });
199
202
  }
200
203
  }
201
204
  if (!remote.isArchived && remote.current) {
@@ -7,8 +7,9 @@ export declare class ClientsSideImpl implements ClientsSide {
7
7
  private readonly asyncReqToListObj;
8
8
  private readonly fnCalls;
9
9
  private fnCallCounter;
10
- private readonly weakRefs;
11
10
  private readonly srvRefs;
11
+ private readonly weakSrvByRefs;
12
+ private readonly srvFinalRegistry;
12
13
  private isStopped;
13
14
  constructor(sendMsg: (msg: Envelope) => void, syncReqToListObj: Caller['listObj'], asyncReqToListObj: Caller['listObjAsync']);
14
15
  stop(exc: IPCException): void;
@@ -25,9 +26,10 @@ export declare class ClientsSideImpl implements ClientsSide {
25
26
  startPromiseCall(path: string[], req: EnvelopeBody): Promise<EnvelopeBody>;
26
27
  startObservableCall(path: string[], req: EnvelopeBody, obs: Subject<EnvelopeBody>): () => void;
27
28
  registerClientDrop(o: any, srvRef: ObjectReference<any>): void;
28
- private makeClientDropCB;
29
+ private doOnClientObjDrop;
29
30
  private sendObjDropMsg;
30
31
  srvRefOf(clientObj: any): ObjectReference<any>;
32
+ findCallingObjByRef<T>(ref: ObjectReference<any>): T | undefined;
31
33
  listObj(path: string[]): string[];
32
34
  listObjAsync(path: string[]): Promise<string[]>;
33
35
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2020 - 2022 3NSoft Inc.
3
+ Copyright (C) 2020 - 2023 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -19,11 +19,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.ClientsSideImpl = void 0;
20
20
  const protobuf_msg_1 = require("./protobuf-msg");
21
21
  const deferred_1 = require("../lib-common/processes/deferred");
22
- const weakref_1 = require("../lib-common/weakref");
23
22
  const connector_1 = require("./connector");
24
23
  const MAX_DUPLICATE_ATTEMPTS = 100;
25
- // XXX can have an optimized use of WeakRef and FinalizationRegistry, when
26
- // these are available.
27
24
  class ClientsSideImpl {
28
25
  constructor(sendMsg, syncReqToListObj, asyncReqToListObj) {
29
26
  this.sendMsg = sendMsg;
@@ -31,8 +28,9 @@ class ClientsSideImpl {
31
28
  this.asyncReqToListObj = asyncReqToListObj;
32
29
  this.fnCalls = new Map();
33
30
  this.fnCallCounter = 1;
34
- this.weakRefs = new Set();
35
31
  this.srvRefs = new WeakMap();
32
+ this.weakSrvByRefs = new Map();
33
+ this.srvFinalRegistry = new FinalizationRegistry(this.doOnClientObjDrop.bind(this));
36
34
  this.isStopped = false;
37
35
  if ((this.asyncReqToListObj && this.syncReqToListObj)
38
36
  || (!this.asyncReqToListObj && !this.syncReqToListObj)) {
@@ -54,10 +52,6 @@ class ClientsSideImpl {
54
52
  }
55
53
  }
56
54
  this.fnCalls.clear();
57
- for (const clientRef of this.weakRefs.values()) {
58
- clientRef.removeCallbacks();
59
- }
60
- this.weakRefs.clear();
61
55
  }
62
56
  sendCallCancellation(fnCallNum) {
63
57
  this.sendMsg({
@@ -169,7 +163,8 @@ class ClientsSideImpl {
169
163
  registerClientDrop: this.registerClientDrop.bind(this),
170
164
  srvRefOf: this.srvRefOf.bind(this),
171
165
  startObservableCall: this.startObservableCall.bind(this),
172
- startPromiseCall: this.startPromiseCall.bind(this)
166
+ startPromiseCall: this.startPromiseCall.bind(this),
167
+ findCallingObjByRef: this.findCallingObjByRef.bind(this)
173
168
  };
174
169
  return callerWrap;
175
170
  }
@@ -217,19 +212,14 @@ class ClientsSideImpl {
217
212
  }
218
213
  }
219
214
  registerClientDrop(o, srvRef) {
220
- const clientRef = (0, weakref_1.makeWeakRefFor)(o);
221
- this.weakRefs.add(clientRef);
222
- clientRef.addCallback(this.makeClientDropCB(clientRef, srvRef));
215
+ o._isObjectFromCore = true;
216
+ this.srvFinalRegistry.register(o, srvRef);
217
+ this.weakSrvByRefs.set(srvRef.path[0], new WeakRef(o));
223
218
  this.srvRefs.set(o, srvRef);
224
- if (global['runningInIsolatedContext']) {
225
- o['--srv-ref'] = srvRef;
226
- }
227
219
  }
228
- makeClientDropCB(clientRef, srvRef) {
229
- return () => {
230
- this.weakRefs.delete(clientRef);
231
- this.sendObjDropMsg(srvRef);
232
- };
220
+ doOnClientObjDrop(srvRef) {
221
+ this.weakSrvByRefs.delete(srvRef.path[0]);
222
+ this.sendObjDropMsg(srvRef);
233
223
  }
234
224
  sendObjDropMsg(srvRef) {
235
225
  if (this.isStopped) {
@@ -238,23 +228,26 @@ class ClientsSideImpl {
238
228
  this.sendMsg({ headers: { msgType: 'drop', path: srvRef.path } });
239
229
  }
240
230
  srvRefOf(clientObj) {
241
- if (global['runningInIsolatedContext']) {
242
- const srvRef = clientObj['--srv-ref'];
243
- if (srvRef) {
244
- return srvRef;
245
- }
246
- else {
247
- throw new Error(`Given object has never been registered as one referencing respective object in the core`);
248
- }
231
+ const srvRef = this.srvRefs.get(clientObj);
232
+ if (srvRef) {
233
+ return srvRef;
249
234
  }
250
235
  else {
251
- const srvRef = this.srvRefs.get(clientObj);
252
- if (srvRef) {
253
- return srvRef;
254
- }
255
- else {
256
- throw (0, connector_1.makeIPCException)({ 'objectNotFound': true });
257
- }
236
+ throw (0, connector_1.makeIPCException)({ 'objectNotFound': true });
237
+ }
238
+ }
239
+ findCallingObjByRef(ref) {
240
+ const weakRef = this.weakSrvByRefs.get(ref.path[0]);
241
+ if (!weakRef) {
242
+ return;
243
+ }
244
+ const o = weakRef.deref();
245
+ if (o) {
246
+ return o;
247
+ }
248
+ else {
249
+ this.weakSrvByRefs.delete(ref.path[0]);
250
+ return;
258
251
  }
259
252
  }
260
253
  listObj(path) {
@@ -1,5 +1,5 @@
1
1
  import { ObjectReference } from "./protobuf-msg";
2
- import { ServicesSide, Envelope, EnvelopeBody, ExposedFn, ExposedObj, ExposedServices } from "./connector";
2
+ import { ServicesSide, Envelope, EnvelopeBody, ExposedFn, ExposedObj, ExposedServices, TransferableObj } from "./connector";
3
3
  export declare class ServicesSideImpl implements ServicesSide {
4
4
  private readonly sendMsg;
5
5
  readonly exposedObjs: ExposedObjs;
@@ -16,8 +16,11 @@ export declare class ServicesSideImpl implements ServicesSide {
16
16
  }
17
17
  export declare class ExposedObjs {
18
18
  private readonly objs;
19
- exposeDroppableService<T>(objType: T, exp: ExposedFn | ExposedObj<any>, original: any): ObjectReference<T>;
19
+ private readonly objToRefs;
20
+ exposeDroppableService<T extends string>(objType: T, exp: ExposedFn | ExposedObj<any>, original: any): ObjectReference<T>;
20
21
  getOriginalObj<T>(ref: ObjectReference<any>): T;
22
+ getObjForTransfer<T extends string>(ref: ObjectReference<T>): TransferableObj<T>;
23
+ findRefIfAlreadyExposed(o: any): ObjectReference<any> | undefined;
21
24
  exposeW3NService(exp: ExposedFn | ExposedObj<any>): void;
22
25
  drop(name: string): void;
23
26
  find(path: string[] | undefined): ExposedFn | ExposedObj<any> | undefined;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2020 - 2021 3NSoft Inc.
3
+ Copyright (C) 2020 - 2021, 2023 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -136,7 +136,9 @@ class ServicesSideImpl {
136
136
  listObj: path => {
137
137
  const obj = this.exposedObjs.find(path);
138
138
  return (obj ? Object.keys(obj) : null);
139
- }
139
+ },
140
+ getObjForTransfer: this.exposedObjs.getObjForTransfer.bind(this.exposedObjs),
141
+ findRefIfAlreadyExposed: this.exposedObjs.findRefIfAlreadyExposed.bind(this.exposedObjs)
140
142
  };
141
143
  return expSrv;
142
144
  }
@@ -147,14 +149,19 @@ Object.freeze(ServicesSideImpl);
147
149
  class ExposedObjs {
148
150
  constructor() {
149
151
  this.objs = new Map();
152
+ this.objToRefs = new Map();
150
153
  }
151
154
  exposeDroppableService(objType, exp, original) {
152
155
  let id;
153
156
  do {
154
157
  id = (0, random_node_1.stringOfB64CharsSync)(20);
155
158
  } while (this.objs.has(id));
156
- this.objs.set(id, { exp, original });
157
- return { objType, path: [id] };
159
+ const ref = {
160
+ objType, path: [id]
161
+ };
162
+ this.objs.set(id, { exp, original, objType });
163
+ this.objToRefs.set(original, ref);
164
+ return ref;
158
165
  }
159
166
  getOriginalObj(ref) {
160
167
  const o = this.objs.get(ref.path[0]);
@@ -165,15 +172,36 @@ class ExposedObjs {
165
172
  throw (0, connector_1.makeIPCException)({ 'objectNotFound': true });
166
173
  }
167
174
  }
175
+ getObjForTransfer(ref) {
176
+ const o = this.objs.get(ref.path[0]);
177
+ if (!o) {
178
+ throw (0, connector_1.makeIPCException)({ 'objectNotFound': true });
179
+ }
180
+ else if (ref.objType !== o.objType) {
181
+ throw (0, connector_1.makeIPCException)({ 'invalidReference': true });
182
+ }
183
+ else {
184
+ return { o: o.original, type: o.objType };
185
+ }
186
+ }
187
+ findRefIfAlreadyExposed(o) {
188
+ return this.objToRefs.get(o);
189
+ }
168
190
  exposeW3NService(exp) {
169
191
  if (this.objs.has(connector_1.W3N_NAME)) {
170
192
  throw new Error(`${connector_1.W3N_NAME} object has already been added`);
171
193
  }
172
- this.objs.set(connector_1.W3N_NAME, { exp, original: undefined });
194
+ this.objs.set(connector_1.W3N_NAME, {
195
+ exp, original: undefined, objType: 'non-transferable'
196
+ });
173
197
  }
174
198
  drop(name) {
175
199
  if (name !== connector_1.W3N_NAME) {
176
- this.objs.delete(name);
200
+ const o = this.objs.get(name);
201
+ if (o) {
202
+ this.objs.delete(name);
203
+ this.objToRefs.delete(o);
204
+ }
177
205
  }
178
206
  }
179
207
  find(path) {
@@ -204,6 +232,7 @@ class ExposedObjs {
204
232
  }
205
233
  dropAll() {
206
234
  this.objs.clear();
235
+ this.objToRefs.clear();
207
236
  }
208
237
  }
209
238
  exports.ExposedObjs = ExposedObjs;
@@ -3,10 +3,16 @@ import { Observer, SubjectLike, Subscribable } from "rxjs";
3
3
  import { ObjectReference, Value } from "./protobuf-msg";
4
4
  import { ProtoType } from '../lib-client/protobuf-type';
5
5
  export interface ExposedServices {
6
- exposeDroppableService<T>(objType: T, exp: ExposedFn | ExposedObj<any>, original: any): ObjectReference<T>;
6
+ exposeDroppableService<T extends string>(objType: T, exp: ExposedFn | ExposedObj<any>, original: any): ObjectReference<T>;
7
7
  getOriginalObj<T>(ref: ObjectReference<any>): T;
8
8
  exposeW3NService(exp: ExposedFn | ExposedObj<any>): void;
9
9
  listObj(path: string[]): string[] | null;
10
+ getObjForTransfer<T extends string>(ref: ObjectReference<T>): TransferableObj<T>;
11
+ findRefIfAlreadyExposed(o: any): ObjectReference<any> | undefined;
12
+ }
13
+ export interface TransferableObj<T extends string> {
14
+ type: T;
15
+ o: any;
10
16
  }
11
17
  export interface ServicesSide {
12
18
  exposedServices(): ExposedServices;
@@ -23,6 +29,10 @@ export interface Caller {
23
29
  srvRefOf(clientObj: any): ObjectReference<any>;
24
30
  listObj?: (path: string[]) => string[];
25
31
  listObjAsync?: (path: string[]) => Promise<string[]>;
32
+ findCallingObjByRef<T>(ref: ObjectReference<any>): T | undefined;
33
+ }
34
+ export interface ObjectFromCore {
35
+ _isObjectFromCore: true;
26
36
  }
27
37
  export interface ClientsSide {
28
38
  caller(): Caller;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2020 - 2022 3NSoft Inc.
3
+ Copyright (C) 2020 - 2023 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
package/build/ipc.d.ts CHANGED
@@ -3,4 +3,5 @@ export * from "./core-ipc/startup-caps";
3
3
  export * from "./ipc-via-protobuf/connector";
4
4
  export { FileMsg, makeFileCaller, exposeFileService } from "./ipc-via-protobuf/file";
5
5
  export { FSMsg, makeFSCaller, exposeFSService } from "./ipc-via-protobuf/fs";
6
+ export { makeSinkCaller, exposeSinkService, makeSrcCaller, exposeSrcService } from "./ipc-via-protobuf/bytes";
6
7
  export { makeLogCaller, exposeLogger } from "./ipc-via-protobuf/log-cap";
package/build/ipc.js CHANGED
@@ -30,7 +30,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
30
30
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.exposeLogger = exports.makeLogCaller = exports.exposeFSService = exports.makeFSCaller = exports.exposeFileService = exports.makeFileCaller = void 0;
33
+ exports.exposeLogger = exports.makeLogCaller = exports.exposeSrcService = exports.makeSrcCaller = exports.exposeSinkService = exports.makeSinkCaller = exports.exposeFSService = exports.makeFSCaller = exports.exposeFileService = exports.makeFileCaller = void 0;
34
34
  __exportStar(require("./core-ipc/common-caps"), exports);
35
35
  __exportStar(require("./core-ipc/startup-caps"), exports);
36
36
  __exportStar(require("./ipc-via-protobuf/connector"), exports);
@@ -40,6 +40,11 @@ Object.defineProperty(exports, "exposeFileService", { enumerable: true, get: fun
40
40
  var fs_1 = require("./ipc-via-protobuf/fs");
41
41
  Object.defineProperty(exports, "makeFSCaller", { enumerable: true, get: function () { return fs_1.makeFSCaller; } });
42
42
  Object.defineProperty(exports, "exposeFSService", { enumerable: true, get: function () { return fs_1.exposeFSService; } });
43
+ var bytes_1 = require("./ipc-via-protobuf/bytes");
44
+ Object.defineProperty(exports, "makeSinkCaller", { enumerable: true, get: function () { return bytes_1.makeSinkCaller; } });
45
+ Object.defineProperty(exports, "exposeSinkService", { enumerable: true, get: function () { return bytes_1.exposeSinkService; } });
46
+ Object.defineProperty(exports, "makeSrcCaller", { enumerable: true, get: function () { return bytes_1.makeSrcCaller; } });
47
+ Object.defineProperty(exports, "exposeSrcService", { enumerable: true, get: function () { return bytes_1.exposeSrcService; } });
43
48
  var log_cap_1 = require("./ipc-via-protobuf/log-cap");
44
49
  Object.defineProperty(exports, "makeLogCaller", { enumerable: true, get: function () { return log_cap_1.makeLogCaller; } });
45
50
  Object.defineProperty(exports, "exposeLogger", { enumerable: true, get: function () { return log_cap_1.exposeLogger; } });
@@ -30,6 +30,7 @@ const rxjs_1 = require("rxjs");
30
30
  const operators_1 = require("rxjs/operators");
31
31
  const attrs_1 = require("./attrs");
32
32
  const assert_1 = require("../../../lib-common/assert");
33
+ const runtime_1 = require("../../../lib-common/exceptions/runtime");
33
34
  class NodeInFS {
34
35
  constructor(storage, type, name, objId, currentVersion, parentId) {
35
36
  this.storage = storage;
@@ -212,11 +213,14 @@ class NodeInFS {
212
213
  this.writeProc = new synced_1.SingleProc();
213
214
  }
214
215
  if (!awaitPrevChange && this.writeProc.isProcessing()) {
215
- throw (0, file_1.makeFileException)('concurrentUpdate', this.name + ` type ${this.type}`);
216
+ throw (0, runtime_1.makeRuntimeException)('file', { path: this.name, fsEtityType: this.type }, { concurrentUpdate: true });
216
217
  }
217
218
  const res = await this.writeProc.startOrChain(async () => {
218
219
  if (this.currentVersion < 0) {
219
- throw (0, file_1.makeFileException)('notFound', this.name, `Object is marked removed`);
220
+ throw (0, runtime_1.makeRuntimeException)('file', {
221
+ path: this.name, fsEtityType: this.type,
222
+ message: `NodeInFS is marked removed`
223
+ }, { notFound: true });
220
224
  }
221
225
  try {
222
226
  const res = await change();