@vuu-ui/vuu-data-remote 3.0.0 → 3.1.0-beta.2

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.
Files changed (70) hide show
  1. package/package.json +18 -13
  2. package/src/ConnectionManager.js +134 -0
  3. package/src/DedicatedWorker.js +44 -0
  4. package/src/LostConnectionHandler.js +89 -0
  5. package/src/VuuAuthProvider.js +78 -0
  6. package/src/VuuAuthenticator.js +36 -0
  7. package/src/VuuDataSource.js +573 -0
  8. package/src/WebSocketConnection.js +149 -0
  9. package/src/authenticate.js +50 -0
  10. package/src/constants.js +45 -0
  11. package/src/data-source.js +57 -0
  12. package/src/index.js +11 -0
  13. package/src/message-utils.js +55 -0
  14. package/src/server-proxy/array-backed-moving-window.js +172 -0
  15. package/src/server-proxy/messages.js +34 -0
  16. package/src/server-proxy/server-proxy.js +817 -0
  17. package/src/server-proxy/viewport.js +608 -0
  18. package/src/worker.js +65 -0
  19. package/cjs/ConnectionManager.js +0 -181
  20. package/cjs/ConnectionManager.js.map +0 -1
  21. package/cjs/DedicatedWorker.js +0 -61
  22. package/cjs/DedicatedWorker.js.map +0 -1
  23. package/cjs/LostConnectionHandler.js +0 -83
  24. package/cjs/LostConnectionHandler.js.map +0 -1
  25. package/cjs/VuuAuthProvider.js +0 -87
  26. package/cjs/VuuAuthProvider.js.map +0 -1
  27. package/cjs/VuuAuthenticator.js +0 -57
  28. package/cjs/VuuAuthenticator.js.map +0 -1
  29. package/cjs/VuuDataSource.js +0 -689
  30. package/cjs/VuuDataSource.js.map +0 -1
  31. package/cjs/WebSocketConnection.js +0 -20
  32. package/cjs/WebSocketConnection.js.map +0 -1
  33. package/cjs/authenticate.js +0 -64
  34. package/cjs/authenticate.js.map +0 -1
  35. package/cjs/constants.js +0 -50
  36. package/cjs/constants.js.map +0 -1
  37. package/cjs/data-source.js +0 -49
  38. package/cjs/data-source.js.map +0 -1
  39. package/cjs/index.js +0 -38
  40. package/cjs/index.js.map +0 -1
  41. package/cjs/inlined-worker.js +0 -2798
  42. package/cjs/inlined-worker.js.map +0 -1
  43. package/cjs/message-utils.js +0 -86
  44. package/cjs/message-utils.js.map +0 -1
  45. package/esm/ConnectionManager.js +0 -179
  46. package/esm/ConnectionManager.js.map +0 -1
  47. package/esm/DedicatedWorker.js +0 -59
  48. package/esm/DedicatedWorker.js.map +0 -1
  49. package/esm/LostConnectionHandler.js +0 -79
  50. package/esm/LostConnectionHandler.js.map +0 -1
  51. package/esm/VuuAuthProvider.js +0 -85
  52. package/esm/VuuAuthProvider.js.map +0 -1
  53. package/esm/VuuAuthenticator.js +0 -54
  54. package/esm/VuuAuthenticator.js.map +0 -1
  55. package/esm/VuuDataSource.js +0 -687
  56. package/esm/VuuDataSource.js.map +0 -1
  57. package/esm/WebSocketConnection.js +0 -17
  58. package/esm/WebSocketConnection.js.map +0 -1
  59. package/esm/authenticate.js +0 -60
  60. package/esm/authenticate.js.map +0 -1
  61. package/esm/constants.js +0 -47
  62. package/esm/constants.js.map +0 -1
  63. package/esm/data-source.js +0 -44
  64. package/esm/data-source.js.map +0 -1
  65. package/esm/index.js +0 -11
  66. package/esm/index.js.map +0 -1
  67. package/esm/inlined-worker.js +0 -2796
  68. package/esm/inlined-worker.js.map +0 -1
  69. package/esm/message-utils.js +0 -80
  70. package/esm/message-utils.js.map +0 -1
@@ -0,0 +1,573 @@
1
+ import { BaseDataSource, Range, StaleUpdateError, combineFilters, constrainRange, debounce, isConfigChanged, isRpcSuccess, isSelectSuccessWithRowCount, isViewportMenusAction, isVisualLinksAction, itemsOrOrderChanged, logger, throttle, uuid } from "@vuu-ui/vuu-utils";
2
+ import ConnectionManager from "./ConnectionManager.js";
3
+ import { isDataSourceConfigMessage } from "./data-source.js";
4
+ const { info: info, infoEnabled: infoEnabled } = logger("VuuDataSource");
5
+ const combineColumnsWithAutosubscribeColumns = (columns, autosubscribeColumns = [])=>{
6
+ if (0 === autosubscribeColumns.length) return columns;
7
+ {
8
+ const out = columns.slice();
9
+ autosubscribeColumns.forEach((name)=>{
10
+ if (!out.includes(name)) out.push(name);
11
+ });
12
+ return out;
13
+ }
14
+ };
15
+ class VuuDataSource extends BaseDataSource {
16
+ bufferSize;
17
+ server = null;
18
+ rangeRequest;
19
+ #allColumns;
20
+ #autosubscribeColumns = [];
21
+ #pendingVisualLink;
22
+ #links;
23
+ #maxRangeEnd = Number.MAX_SAFE_INTEGER;
24
+ #maxRangeWidth = Number.MAX_SAFE_INTEGER;
25
+ #menu;
26
+ #optimize = "throttle";
27
+ #selectedRowsCount = 0;
28
+ #sessionDataSource = void 0;
29
+ #sessionTableMessageColumn = void 0;
30
+ #status = "initialising";
31
+ #tableSchema;
32
+ table;
33
+ constructor({ sessionTableMessageColumn, ...props }){
34
+ super(props);
35
+ const { bufferSize = 100, table, visualLink } = props;
36
+ if (!table) throw Error("RemoteDataSource constructor called without table");
37
+ this.bufferSize = bufferSize;
38
+ this.table = table;
39
+ this.#pendingVisualLink = visualLink;
40
+ this.#sessionTableMessageColumn = sessionTableMessageColumn;
41
+ this.rangeRequest = this.rawRangeRequest;
42
+ if (props.autosubscribeColumns) {
43
+ this.#autosubscribeColumns = props.autosubscribeColumns;
44
+ this.#allColumns = combineColumnsWithAutosubscribeColumns(super.columns, props.autosubscribeColumns);
45
+ }
46
+ }
47
+ async subscribe(subscribeProps, callback) {
48
+ super.subscribe(subscribeProps, callback);
49
+ const { viewport = this.viewport || (this.viewport = uuid()) } = subscribeProps;
50
+ if ("disabled" === this.#status || "disabling" === this.#status || "enabling" === this.#status) return void this.enable(callback);
51
+ if ("initialising" !== this.#status && "unsubscribed" !== this.#status) throw Error(`[VuuDataSource] invalid status ${this.#status} for subscribe`);
52
+ this.#status = "subscribing";
53
+ this.server = await ConnectionManager.serverAPI;
54
+ const { bufferSize } = this;
55
+ const { columns, ...dataSourceConfig } = combineFilters(this.config);
56
+ this.server?.subscribe({
57
+ ...dataSourceConfig,
58
+ bufferSize,
59
+ columns: this.columns,
60
+ range: this._range.withBuffer,
61
+ table: this.table,
62
+ title: this._title,
63
+ viewport
64
+ }, this.handleMessageFromServer);
65
+ }
66
+ handleMessageFromServer = (message)=>{
67
+ if ("subscribed" === message.type) {
68
+ this.#status = "subscribed";
69
+ this.tableSchema = message.tableSchema;
70
+ if (message.tableSchema.rangeLimits) {
71
+ this.#maxRangeEnd = message.tableSchema.rangeLimits.maxRangeEnd;
72
+ this.#maxRangeWidth = message.tableSchema.rangeLimits.maxRangeWidth;
73
+ }
74
+ this._clientCallback?.(message);
75
+ if (this.#pendingVisualLink) {
76
+ this.visualLink = this.#pendingVisualLink;
77
+ this.#pendingVisualLink = void 0;
78
+ }
79
+ this.emit("subscribed", message);
80
+ } else if ("disabled" === message.type) this.#status = "disabled";
81
+ else if ("enabled" === message.type) {
82
+ this.#status = "subscribed";
83
+ this.emit("enabled", this.viewport);
84
+ } else if (isDataSourceConfigMessage(message)) return;
85
+ else if ("debounce-begin" === message.type) this.optimize = "debounce";
86
+ else {
87
+ if ("viewport-update" === message.type) {
88
+ if (void 0 !== message.size && message.size !== this.size) {
89
+ this.size = message.size;
90
+ this.emit("resize", message.size, this.#maxRangeEnd);
91
+ }
92
+ if (Array.isArray(message.rows) && message.rows.length > 0 && this.#sessionDataSource) {
93
+ this.emit("remote-update-during-local-edit", message.rows);
94
+ console.log(`updates incoming whilst edit in progress ${this.viewport}`);
95
+ console.table(message.rows);
96
+ return;
97
+ }
98
+ } else if ("viewport-clear" === message.type) {
99
+ this.size = 0;
100
+ this.emit("resize", 0);
101
+ }
102
+ if (this.isAwaitingConfirmationOfConfigChange) this.confirmConfigChange();
103
+ if (isViewportMenusAction(message)) this.#menu = message.menu;
104
+ else if (isVisualLinksAction(message)) this.#links = message.links;
105
+ else {
106
+ if (infoEnabled && "viewport-update" === message.type) info(`handleMessageFromServer<viewport-update> range (${message.range?.from}:${message.range?.to}) rows ${message.rows?.at(0)?.[0]} - ${message.rows?.at(-1)?.[0]}`);
107
+ this._clientCallback?.(message);
108
+ }
109
+ if ("debounce" === this.optimize) this.revertDebounce();
110
+ }
111
+ };
112
+ handleSessionMessageFromServer = (msg)=>{
113
+ if ("subscribed" === msg.type) console.log("[VuuDataSource subscribed to session table]");
114
+ else if ("viewport-update" === msg.type) {
115
+ if (void 0 !== msg.size && msg.size !== this.size) {
116
+ this.size = msg.size;
117
+ this.emit("resize", msg.size);
118
+ }
119
+ this._clientCallback?.(msg);
120
+ }
121
+ };
122
+ unsubscribe() {
123
+ if ("unsubscribed" !== this.#status) {
124
+ info?.(`unsubscribe #${this.viewport}`);
125
+ if (this.viewport) {
126
+ this.server?.unsubscribe(this.viewport);
127
+ this.emit("unsubscribed", this.viewport);
128
+ }
129
+ this.server?.destroy(this.viewport);
130
+ this.server = null;
131
+ this.removeAllListeners();
132
+ this.#status = "unsubscribed";
133
+ this.viewport = "";
134
+ this.range = Range(0, 0);
135
+ }
136
+ }
137
+ suspend(escalateToDisable = this._defaultSuspenseProps.escalateToDisable, escalateDelay = this._defaultSuspenseProps.escalateDelay) {
138
+ if ("unsubscribed" !== this.#status) {
139
+ info?.(`suspend #${this.viewport}, current status ${this.#status}`);
140
+ if (this.viewport) {
141
+ this.#status = "suspended";
142
+ this.server?.send({
143
+ escalateDelay,
144
+ escalateToDisable,
145
+ type: "suspend",
146
+ viewport: this.viewport
147
+ });
148
+ this.emit("suspended", this.viewport);
149
+ }
150
+ }
151
+ }
152
+ sendResumeMessage() {
153
+ this.server?.send({
154
+ type: "resume",
155
+ viewport: this.viewport
156
+ });
157
+ }
158
+ resume(callback) {
159
+ const isDisabled = this.#status.startsWith("disabl");
160
+ const isSuspended = "suspended" === this.#status;
161
+ info?.(`resume #${this.viewport}, current status ${this.#status}`);
162
+ if (callback) this._clientCallback = callback;
163
+ if (this.viewport) {
164
+ if (isDisabled) this.enable();
165
+ else if (isSuspended) {
166
+ this.sendResumeMessage();
167
+ this.#status = "subscribed";
168
+ this.emit("resumed", this.viewport);
169
+ if (this.#selectedRowsCount > 0) this.emit("row-selection", this.#selectedRowsCount);
170
+ }
171
+ }
172
+ }
173
+ freeze() {
174
+ super.freeze();
175
+ if (this.viewport) this.server?.send({
176
+ viewport: this.viewport,
177
+ type: "FREEZE_VP"
178
+ });
179
+ }
180
+ unfreeze() {
181
+ super.unfreeze();
182
+ if (this.viewport) this.server?.send({
183
+ viewport: this.viewport,
184
+ type: "UNFREEZE_VP"
185
+ });
186
+ }
187
+ disable() {
188
+ info?.(`disable #${this.viewport}, current status ${this.#status}`);
189
+ if (this.viewport) {
190
+ this.#status = "disabling";
191
+ this.server?.send({
192
+ viewport: this.viewport,
193
+ type: "disable"
194
+ });
195
+ this.emit("disabled", this.viewport);
196
+ }
197
+ }
198
+ enable(callback) {
199
+ info?.(`enable #${this.viewport}, current status ${this.#status}`);
200
+ if (this.viewport && ("disabled" === this.#status || "disabling" === this.#status)) {
201
+ this.#status = "enabling";
202
+ if (callback) this._clientCallback = callback;
203
+ this.server?.send({
204
+ viewport: this.viewport,
205
+ type: "enable"
206
+ });
207
+ this.emit("enabled", this.viewport);
208
+ }
209
+ }
210
+ async select(selectRequest) {
211
+ if (this.viewport && this.server) {
212
+ const response = await this.server.select({
213
+ ...selectRequest,
214
+ vpId: this.viewport
215
+ });
216
+ if (isSelectSuccessWithRowCount(response)) {
217
+ this.#selectedRowsCount = response.selectedRowCount;
218
+ this.emit("row-selection", response.selectedRowCount);
219
+ } else console.warn("select error");
220
+ }
221
+ }
222
+ openTreeNode(keyOrIndex) {
223
+ if (this.viewport) {
224
+ const [key, index] = "string" == typeof keyOrIndex ? [
225
+ keyOrIndex
226
+ ] : [
227
+ void 0,
228
+ keyOrIndex
229
+ ];
230
+ this.server?.send({
231
+ index,
232
+ key,
233
+ type: "openTreeNode",
234
+ viewport: this.viewport
235
+ });
236
+ }
237
+ }
238
+ closeTreeNode(keyOrIndex) {
239
+ if (this.viewport) {
240
+ const [key, index] = "string" == typeof keyOrIndex ? [
241
+ keyOrIndex
242
+ ] : [
243
+ void 0,
244
+ keyOrIndex
245
+ ];
246
+ this.server?.send({
247
+ index,
248
+ key,
249
+ type: "closeTreeNode",
250
+ viewport: this.viewport
251
+ });
252
+ }
253
+ }
254
+ get columns() {
255
+ return this.#allColumns ?? super.columns;
256
+ }
257
+ set columns(columns) {
258
+ super.columns = columns;
259
+ if (this.#autosubscribeColumns.length) this.#allColumns = combineColumnsWithAutosubscribeColumns(columns, this.#autosubscribeColumns);
260
+ }
261
+ get tableSchema() {
262
+ return this.#tableSchema;
263
+ }
264
+ set tableSchema(tableSchema) {
265
+ this.#tableSchema = tableSchema;
266
+ }
267
+ get links() {
268
+ return this.#links;
269
+ }
270
+ get maxRangeEnd() {
271
+ return this.#maxRangeEnd;
272
+ }
273
+ get menu() {
274
+ return this.#menu;
275
+ }
276
+ get status() {
277
+ return this.#status;
278
+ }
279
+ get optimize() {
280
+ return this.#optimize;
281
+ }
282
+ set optimize(optimize) {
283
+ if (optimize !== this.#optimize) {
284
+ this.#optimize = optimize;
285
+ switch(optimize){
286
+ case "none":
287
+ this.rangeRequest = this.rawRangeRequest;
288
+ break;
289
+ case "debounce":
290
+ this.rangeRequest = this.debounceRangeRequest;
291
+ break;
292
+ case "throttle":
293
+ this.rangeRequest = this.throttleRangeRequest;
294
+ break;
295
+ }
296
+ this.emit("optimize", optimize);
297
+ }
298
+ }
299
+ revertDebounce = debounce(()=>{
300
+ this.optimize = "throttle";
301
+ }, 100);
302
+ get selectedRowsCount() {
303
+ return this.#selectedRowsCount;
304
+ }
305
+ rawRangeRequest = (range)=>{
306
+ if (this.viewport && this.server) this.server.send({
307
+ viewport: this.viewport,
308
+ type: "setViewRange",
309
+ range: constrainRange(range, this.#maxRangeEnd, this.#maxRangeWidth)
310
+ });
311
+ };
312
+ debounceRangeRequest = debounce((range)=>{
313
+ if (this.viewport && this.server) this.server.send({
314
+ viewport: this.viewport,
315
+ type: "setViewRange",
316
+ range: constrainRange(range, this.#maxRangeEnd, this.#maxRangeWidth)
317
+ });
318
+ }, 50);
319
+ throttleRangeRequest = throttle((range)=>{
320
+ if (this.viewport && this.server) this.server.send({
321
+ viewport: this.viewport,
322
+ type: "setViewRange",
323
+ range: constrainRange(range, this.#maxRangeEnd, this.#maxRangeWidth)
324
+ });
325
+ }, 80);
326
+ get config() {
327
+ return super.config;
328
+ }
329
+ set config(config) {
330
+ const { noChanges, columnsChanged } = isConfigChanged(this.config, config);
331
+ if (!noChanges) {
332
+ super.config = config;
333
+ const { columns, ...dataSourceConfig } = combineFilters(this.config);
334
+ const serverConfig = {
335
+ ...dataSourceConfig,
336
+ columns: combineColumnsWithAutosubscribeColumns(columns, this.#autosubscribeColumns)
337
+ };
338
+ if (columnsChanged && this.#autosubscribeColumns.length) this.#allColumns = combineColumnsWithAutosubscribeColumns(columns, this.#autosubscribeColumns);
339
+ this.server?.send({
340
+ viewport: this.viewport,
341
+ type: "config",
342
+ config: serverConfig
343
+ });
344
+ }
345
+ }
346
+ set impendingConfig(config) {
347
+ if (config !== this.config) {
348
+ super.impendingConfig = config;
349
+ this.server?.send({
350
+ viewport: this.viewport,
351
+ type: "config",
352
+ config: combineFilters(this.config)
353
+ });
354
+ }
355
+ }
356
+ get groupBy() {
357
+ return this._configWithVisualLink.groupBy;
358
+ }
359
+ set groupBy(groupBy) {
360
+ if (itemsOrOrderChanged(this.groupBy, groupBy)) {
361
+ const wasGrouped = this.groupBy.length > 0;
362
+ this.impendingConfig = {
363
+ ...this._configWithVisualLink,
364
+ groupBy
365
+ };
366
+ if (!wasGrouped && groupBy.length > 0 && this.viewport) this._clientCallback?.({
367
+ clientViewportId: this.viewport,
368
+ mode: "batch",
369
+ type: "viewport-update",
370
+ size: 0,
371
+ rows: []
372
+ });
373
+ }
374
+ }
375
+ get range() {
376
+ return super.range;
377
+ }
378
+ set range(range) {
379
+ super.range = range;
380
+ if (this.#sessionDataSource) this.#sessionDataSource.range = range;
381
+ }
382
+ get title() {
383
+ return super.title || `${this.table.module} ${this.table.table}`;
384
+ }
385
+ set title(title) {
386
+ super.title = title;
387
+ if (this.viewport && title) this.server?.send({
388
+ type: "setTitle",
389
+ title,
390
+ viewport: this.viewport
391
+ });
392
+ }
393
+ get visualLink() {
394
+ return this._configWithVisualLink.visualLink;
395
+ }
396
+ set visualLink(visualLink) {
397
+ this._configWithVisualLink = {
398
+ ...this._configWithVisualLink,
399
+ visualLink
400
+ };
401
+ if (visualLink) {
402
+ const { parentClientVpId, link: { fromColumn, toColumn } } = visualLink;
403
+ if (this.viewport) this.server?.rpcCall({
404
+ childColumnName: fromColumn,
405
+ childVpId: this.viewport,
406
+ parentColumnName: toColumn,
407
+ parentVpId: parentClientVpId,
408
+ type: "CREATE_VISUAL_LINK"
409
+ }).then((response)=>{
410
+ this.emit("visual-link-created", response);
411
+ });
412
+ } else if (this.viewport) this.server?.rpcCall({
413
+ type: "REMOVE_VISUAL_LINK",
414
+ childVpId: this.viewport
415
+ }).then(()=>{
416
+ this.emit("visual-link-removed");
417
+ });
418
+ this.emit("config", this._configWithVisualLink, this.range);
419
+ }
420
+ async remoteProcedureCall() {
421
+ return Promise.reject();
422
+ }
423
+ async createSessionDataSource(copyOption) {
424
+ const rpcResponse = await this?.rpcRequest?.({
425
+ type: "RPC_REQUEST",
426
+ rpcName: "createSessionTable",
427
+ params: {
428
+ copyOption
429
+ }
430
+ });
431
+ if (isRpcSuccess(rpcResponse)) {
432
+ const { table: sessionTable } = rpcResponse.data;
433
+ return new VuuDataSource({
434
+ ...this.config,
435
+ table: sessionTable,
436
+ viewport: sessionTable.table
437
+ });
438
+ }
439
+ throw Error(`[VuuDataSource] createSessionDataSource ${rpcResponse?.errorMessage}`);
440
+ }
441
+ async beginEditSession(editSessionMode = "all-rows") {
442
+ const rpcResponse = await this?.rpcRequest?.({
443
+ type: "RPC_REQUEST",
444
+ rpcName: "beginEditSession",
445
+ params: {
446
+ editSessionMode
447
+ }
448
+ });
449
+ if (isRpcSuccess(rpcResponse)) {
450
+ const { table: sessionTable } = rpcResponse.data;
451
+ const columns = this.#sessionTableMessageColumn ? this.columns.concat(this.#sessionTableMessageColumn) : this.columns;
452
+ this.#sessionDataSource = new VuuDataSource({
453
+ ...this.config,
454
+ columns,
455
+ table: sessionTable,
456
+ viewport: sessionTable.table
457
+ });
458
+ this.#sessionDataSource.subscribe({
459
+ range: this.range
460
+ }, this.handleSessionMessageFromServer);
461
+ } else throw Error(`[VuuDataSource] beginEditSession ${rpcResponse.errorMessage}`);
462
+ }
463
+ async editCell(key, column, data) {
464
+ const rpcHost = this.#sessionDataSource ?? this;
465
+ return rpcHost.rpcRequest?.({
466
+ type: "RPC_REQUEST",
467
+ rpcName: "editCell",
468
+ params: {
469
+ column,
470
+ data,
471
+ key
472
+ }
473
+ });
474
+ }
475
+ async endEditSession(saveChanges = false, force = false) {
476
+ const type = "RPC_REQUEST";
477
+ const rpcName = "endEditSession";
478
+ const sessionDataSource = this.#sessionDataSource;
479
+ const rpcHost = sessionDataSource ?? this;
480
+ if (sessionDataSource) this.#sessionDataSource = void 0;
481
+ const rpcResponse = await rpcHost.rpcRequest?.(saveChanges ? {
482
+ type,
483
+ rpcName,
484
+ params: {
485
+ save: true,
486
+ force
487
+ }
488
+ } : {
489
+ type,
490
+ rpcName,
491
+ params: {}
492
+ });
493
+ if (isRpcSuccess(rpcResponse)) {
494
+ if (sessionDataSource) sessionDataSource?.unsubscribe();
495
+ } else if (rpcResponse?.errorMessage === "stale update") {
496
+ this.#sessionDataSource = sessionDataSource;
497
+ throw new StaleUpdateError(rpcResponse.errorMessage);
498
+ } else throw Error("unknown error");
499
+ this.sendResumeMessage();
500
+ }
501
+ async rpcRequest(rpcRequest) {
502
+ if (this.viewport && this.server) return this.server?.rpcCall({
503
+ ...rpcRequest,
504
+ context: {
505
+ type: "VIEWPORT_CONTEXT",
506
+ viewPortId: this.viewport
507
+ }
508
+ });
509
+ throw Error("rpcCall server or viewport are undefined");
510
+ }
511
+ async menuRpcCall(rpcRequest) {
512
+ if (this.viewport) return this.server?.rpcCall({
513
+ ...rpcRequest,
514
+ vpId: this.viewport
515
+ });
516
+ }
517
+ insertRow() {
518
+ return Promise.resolve("not supported");
519
+ }
520
+ async deleteRow(key, mode = "hard") {
521
+ const rpcHost = this.#sessionDataSource ?? this;
522
+ const response = await rpcHost.rpcRequest?.({
523
+ type: "RPC_REQUEST",
524
+ rpcName: "deleteRow",
525
+ params: {
526
+ key,
527
+ mode
528
+ }
529
+ });
530
+ if (isRpcSuccess(response)) return true;
531
+ return response?.errorMessage ?? "deleteRow failed";
532
+ }
533
+ async deleteSelectedRows(mode = "soft") {
534
+ const rpcHost = this.#sessionDataSource ?? this;
535
+ const response = await rpcHost.rpcRequest?.({
536
+ type: "RPC_REQUEST",
537
+ rpcName: "deleteSelectedRows",
538
+ params: {
539
+ mode
540
+ }
541
+ });
542
+ return response ?? {
543
+ type: "ERROR_RESULT",
544
+ errorMessage: "deleteSelectedRows failed"
545
+ };
546
+ }
547
+ async addRow(rowData = {}) {
548
+ const response = await this.rpcRequest?.({
549
+ type: "RPC_REQUEST",
550
+ rpcName: "addRow",
551
+ params: {
552
+ data: rowData
553
+ }
554
+ });
555
+ if (isRpcSuccess(response)) return true;
556
+ return response?.errorMessage ?? "addRow failed";
557
+ }
558
+ async undoRowChange(key) {
559
+ const rpcHost = this.#sessionDataSource ?? this;
560
+ const response = await rpcHost.rpcRequest?.({
561
+ type: "RPC_REQUEST",
562
+ rpcName: "undoRowChange",
563
+ params: {
564
+ key
565
+ }
566
+ });
567
+ return response ?? {
568
+ type: "ERROR_RESULT",
569
+ errorMessage: "undoRowChange failed"
570
+ };
571
+ }
572
+ }
573
+ export { VuuDataSource };