@vuu-ui/vuu-data-test 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 (264) hide show
  1. package/package.json +15 -12
  2. package/src/ArrayProxy.js +38 -0
  3. package/src/RuntimeVisualLink.js +45 -0
  4. package/src/Table.js +96 -0
  5. package/src/TickingArrayDataSource.js +265 -0
  6. package/src/UpdateGenerator.js +72 -0
  7. package/src/basket/BasketModule.js +272 -0
  8. package/src/basket/basket-schemas.js +366 -0
  9. package/src/basket/index.js +2 -0
  10. package/src/basket/reference-data/constituents.js +76 -0
  11. package/src/basket/reference-data/ftse100.js +686 -0
  12. package/src/basket/reference-data/hsi.js +1047 -0
  13. package/src/basket/reference-data/nasdaq100.js +812 -0
  14. package/src/basket/reference-data/prices.js +43 -0
  15. package/src/basket/reference-data/sp500.js +315 -0
  16. package/src/core/module/ModuleContainer.js +21 -0
  17. package/src/core/module/VuuModule.js +635 -0
  18. package/src/core/table/TableContainer.js +102 -0
  19. package/src/data-utils.js +57 -0
  20. package/src/default-column-definitions.js +15 -0
  21. package/src/index.js +12 -0
  22. package/src/local-datasource-provider/LocalDatasourceProvider.js +44 -0
  23. package/src/makeSuggestions.js +20 -0
  24. package/src/rowUpdates.js +0 -0
  25. package/src/schemas.js +19 -0
  26. package/src/session-table-utils.js +31 -0
  27. package/src/simul/SimulModule.js +175 -0
  28. package/src/simul/index.js +2 -0
  29. package/src/simul/reference-data/accounts.js +23 -0
  30. package/src/simul/reference-data/algos.js +9 -0
  31. package/src/simul/reference-data/currencies.js +8 -0
  32. package/src/simul/reference-data/index.js +5 -0
  33. package/src/simul/reference-data/instrument-prices.js +48 -0
  34. package/src/simul/reference-data/instruments-extended.js +12 -0
  35. package/src/simul/reference-data/instruments.js +69 -0
  36. package/src/simul/reference-data/isin-generator/convert-string-to-base-ten-number.js +2 -0
  37. package/src/simul/reference-data/isin-generator/fixtures/alphabet.js +27 -0
  38. package/src/simul/reference-data/isin-generator/fixtures/alphanumeric-values.js +7 -0
  39. package/src/simul/reference-data/isin-generator/fixtures/base-ten-numbers.js +13 -0
  40. package/src/simul/reference-data/isin-generator/generate-cusip-check-code.js +17 -0
  41. package/src/simul/reference-data/isin-generator/generate-cusip-without-check-code.js +8 -0
  42. package/src/simul/reference-data/isin-generator/generate-cusip.js +8 -0
  43. package/src/simul/reference-data/isin-generator/generate-random-alphanumeric.js +3 -0
  44. package/src/simul/reference-data/isin-generator/generate-random-base-ten-number.js +2 -0
  45. package/src/simul/reference-data/isin-generator/generate-random-string-of-alphanumeric-chars.js +7 -0
  46. package/src/simul/reference-data/isin-generator/generate-random-string-of-base-ten-chars.js +7 -0
  47. package/src/simul/reference-data/isin-generator/index.js +280 -0
  48. package/src/simul/reference-data/isin-generator/is-odd.js +2 -0
  49. package/src/simul/reference-data/locations.js +45 -0
  50. package/src/simul/reference-data/lotsizes.js +24 -0
  51. package/src/simul/reference-data/orderStatus.js +6 -0
  52. package/src/simul/reference-data/orders.js +64 -0
  53. package/src/simul/reference-data/parent-child-orders.js +119 -0
  54. package/src/simul/reference-data/priceStrategies.js +8 -0
  55. package/src/simul/reference-data/prices.js +80 -0
  56. package/src/simul/reference-data/sides.js +5 -0
  57. package/src/simul/simul-schemas.js +430 -0
  58. package/src/test/TestModule.js +582 -0
  59. package/src/test/index.js +1 -0
  60. package/src/vuu-row-generator.js +71 -0
  61. package/cjs/ArrayProxy.js +0 -72
  62. package/cjs/ArrayProxy.js.map +0 -1
  63. package/cjs/RuntimeVisualLink.js +0 -73
  64. package/cjs/RuntimeVisualLink.js.map +0 -1
  65. package/cjs/Table.js +0 -128
  66. package/cjs/Table.js.map +0 -1
  67. package/cjs/TickingArrayDataSource.js +0 -343
  68. package/cjs/TickingArrayDataSource.js.map +0 -1
  69. package/cjs/UpdateGenerator.js +0 -94
  70. package/cjs/UpdateGenerator.js.map +0 -1
  71. package/cjs/basket/BasketModule.js +0 -282
  72. package/cjs/basket/BasketModule.js.map +0 -1
  73. package/cjs/basket/basket-schemas.js +0 -134
  74. package/cjs/basket/basket-schemas.js.map +0 -1
  75. package/cjs/basket/reference-data/constituents.js +0 -40
  76. package/cjs/basket/reference-data/constituents.js.map +0 -1
  77. package/cjs/basket/reference-data/ftse100.js +0 -105
  78. package/cjs/basket/reference-data/ftse100.js.map +0 -1
  79. package/cjs/basket/reference-data/hsi.js +0 -87
  80. package/cjs/basket/reference-data/hsi.js.map +0 -1
  81. package/cjs/basket/reference-data/nasdaq100.js +0 -108
  82. package/cjs/basket/reference-data/nasdaq100.js.map +0 -1
  83. package/cjs/basket/reference-data/sp500.js +0 -46
  84. package/cjs/basket/reference-data/sp500.js.map +0 -1
  85. package/cjs/core/module/ModuleContainer.js +0 -43
  86. package/cjs/core/module/ModuleContainer.js.map +0 -1
  87. package/cjs/core/module/VuuModule.js +0 -843
  88. package/cjs/core/module/VuuModule.js.map +0 -1
  89. package/cjs/core/table/TableContainer.js +0 -144
  90. package/cjs/core/table/TableContainer.js.map +0 -1
  91. package/cjs/data-utils.js +0 -55
  92. package/cjs/data-utils.js.map +0 -1
  93. package/cjs/default-column-definitions.js +0 -10
  94. package/cjs/default-column-definitions.js.map +0 -1
  95. package/cjs/index.js +0 -44
  96. package/cjs/index.js.map +0 -1
  97. package/cjs/local-datasource-provider/LocalDatasourceProvider.js +0 -70
  98. package/cjs/local-datasource-provider/LocalDatasourceProvider.js.map +0 -1
  99. package/cjs/makeSuggestions.js +0 -26
  100. package/cjs/makeSuggestions.js.map +0 -1
  101. package/cjs/schemas.js +0 -28
  102. package/cjs/schemas.js.map +0 -1
  103. package/cjs/session-table-utils.js +0 -29
  104. package/cjs/session-table-utils.js.map +0 -1
  105. package/cjs/simul/SimulModule.js +0 -187
  106. package/cjs/simul/SimulModule.js.map +0 -1
  107. package/cjs/simul/reference-data/accounts.js +0 -27
  108. package/cjs/simul/reference-data/accounts.js.map +0 -1
  109. package/cjs/simul/reference-data/algos.js +0 -6
  110. package/cjs/simul/reference-data/algos.js.map +0 -1
  111. package/cjs/simul/reference-data/currencies.js +0 -6
  112. package/cjs/simul/reference-data/currencies.js.map +0 -1
  113. package/cjs/simul/reference-data/instruments-extended.js +0 -19
  114. package/cjs/simul/reference-data/instruments-extended.js.map +0 -1
  115. package/cjs/simul/reference-data/instruments.js +0 -87
  116. package/cjs/simul/reference-data/instruments.js.map +0 -1
  117. package/cjs/simul/reference-data/isin-generator/convert-string-to-base-ten-number.js +0 -6
  118. package/cjs/simul/reference-data/isin-generator/convert-string-to-base-ten-number.js.map +0 -1
  119. package/cjs/simul/reference-data/isin-generator/fixtures/alphabet.js +0 -31
  120. package/cjs/simul/reference-data/isin-generator/fixtures/alphabet.js.map +0 -1
  121. package/cjs/simul/reference-data/isin-generator/fixtures/alphanumeric-values.js +0 -9
  122. package/cjs/simul/reference-data/isin-generator/fixtures/alphanumeric-values.js.map +0 -1
  123. package/cjs/simul/reference-data/isin-generator/fixtures/base-ten-numbers.js +0 -17
  124. package/cjs/simul/reference-data/isin-generator/fixtures/base-ten-numbers.js.map +0 -1
  125. package/cjs/simul/reference-data/isin-generator/generate-cusip-check-code.js +0 -24
  126. package/cjs/simul/reference-data/isin-generator/generate-cusip-check-code.js.map +0 -1
  127. package/cjs/simul/reference-data/isin-generator/generate-cusip-without-check-code.js +0 -13
  128. package/cjs/simul/reference-data/isin-generator/generate-cusip-without-check-code.js.map +0 -1
  129. package/cjs/simul/reference-data/isin-generator/generate-cusip.js +0 -13
  130. package/cjs/simul/reference-data/isin-generator/generate-cusip.js.map +0 -1
  131. package/cjs/simul/reference-data/isin-generator/generate-random-alphanumeric.js +0 -8
  132. package/cjs/simul/reference-data/isin-generator/generate-random-alphanumeric.js.map +0 -1
  133. package/cjs/simul/reference-data/isin-generator/generate-random-base-ten-number.js +0 -6
  134. package/cjs/simul/reference-data/isin-generator/generate-random-base-ten-number.js.map +0 -1
  135. package/cjs/simul/reference-data/isin-generator/generate-random-string-of-alphanumeric-chars.js +0 -14
  136. package/cjs/simul/reference-data/isin-generator/generate-random-string-of-alphanumeric-chars.js.map +0 -1
  137. package/cjs/simul/reference-data/isin-generator/generate-random-string-of-base-ten-chars.js +0 -14
  138. package/cjs/simul/reference-data/isin-generator/generate-random-string-of-base-ten-chars.js.map +0 -1
  139. package/cjs/simul/reference-data/isin-generator/index.js +0 -295
  140. package/cjs/simul/reference-data/isin-generator/index.js.map +0 -1
  141. package/cjs/simul/reference-data/isin-generator/is-odd.js +0 -6
  142. package/cjs/simul/reference-data/isin-generator/is-odd.js.map +0 -1
  143. package/cjs/simul/reference-data/locations.js +0 -17
  144. package/cjs/simul/reference-data/locations.js.map +0 -1
  145. package/cjs/simul/reference-data/lotsizes.js +0 -28
  146. package/cjs/simul/reference-data/lotsizes.js.map +0 -1
  147. package/cjs/simul/reference-data/orderStatus.js +0 -6
  148. package/cjs/simul/reference-data/orderStatus.js.map +0 -1
  149. package/cjs/simul/reference-data/orders.js +0 -55
  150. package/cjs/simul/reference-data/orders.js.map +0 -1
  151. package/cjs/simul/reference-data/parent-child-orders.js +0 -146
  152. package/cjs/simul/reference-data/parent-child-orders.js.map +0 -1
  153. package/cjs/simul/reference-data/prices.js +0 -91
  154. package/cjs/simul/reference-data/prices.js.map +0 -1
  155. package/cjs/simul/reference-data/sides.js +0 -6
  156. package/cjs/simul/reference-data/sides.js.map +0 -1
  157. package/cjs/simul/simul-schemas.js +0 -159
  158. package/cjs/simul/simul-schemas.js.map +0 -1
  159. package/cjs/test/TestModule.js +0 -255
  160. package/cjs/test/TestModule.js.map +0 -1
  161. package/cjs/vuu-row-generator.js +0 -74
  162. package/cjs/vuu-row-generator.js.map +0 -1
  163. package/esm/ArrayProxy.js +0 -70
  164. package/esm/ArrayProxy.js.map +0 -1
  165. package/esm/RuntimeVisualLink.js +0 -71
  166. package/esm/RuntimeVisualLink.js.map +0 -1
  167. package/esm/Table.js +0 -124
  168. package/esm/Table.js.map +0 -1
  169. package/esm/TickingArrayDataSource.js +0 -341
  170. package/esm/TickingArrayDataSource.js.map +0 -1
  171. package/esm/UpdateGenerator.js +0 -92
  172. package/esm/UpdateGenerator.js.map +0 -1
  173. package/esm/basket/BasketModule.js +0 -278
  174. package/esm/basket/BasketModule.js.map +0 -1
  175. package/esm/basket/basket-schemas.js +0 -131
  176. package/esm/basket/basket-schemas.js.map +0 -1
  177. package/esm/basket/reference-data/constituents.js +0 -38
  178. package/esm/basket/reference-data/constituents.js.map +0 -1
  179. package/esm/basket/reference-data/ftse100.js +0 -103
  180. package/esm/basket/reference-data/ftse100.js.map +0 -1
  181. package/esm/basket/reference-data/hsi.js +0 -85
  182. package/esm/basket/reference-data/hsi.js.map +0 -1
  183. package/esm/basket/reference-data/nasdaq100.js +0 -106
  184. package/esm/basket/reference-data/nasdaq100.js.map +0 -1
  185. package/esm/basket/reference-data/sp500.js +0 -44
  186. package/esm/basket/reference-data/sp500.js.map +0 -1
  187. package/esm/core/module/ModuleContainer.js +0 -41
  188. package/esm/core/module/ModuleContainer.js.map +0 -1
  189. package/esm/core/module/VuuModule.js +0 -841
  190. package/esm/core/module/VuuModule.js.map +0 -1
  191. package/esm/core/table/TableContainer.js +0 -142
  192. package/esm/core/table/TableContainer.js.map +0 -1
  193. package/esm/data-utils.js +0 -50
  194. package/esm/data-utils.js.map +0 -1
  195. package/esm/default-column-definitions.js +0 -8
  196. package/esm/default-column-definitions.js.map +0 -1
  197. package/esm/index.js +0 -15
  198. package/esm/index.js.map +0 -1
  199. package/esm/local-datasource-provider/LocalDatasourceProvider.js +0 -68
  200. package/esm/local-datasource-provider/LocalDatasourceProvider.js.map +0 -1
  201. package/esm/makeSuggestions.js +0 -24
  202. package/esm/makeSuggestions.js.map +0 -1
  203. package/esm/schemas.js +0 -24
  204. package/esm/schemas.js.map +0 -1
  205. package/esm/session-table-utils.js +0 -26
  206. package/esm/session-table-utils.js.map +0 -1
  207. package/esm/simul/SimulModule.js +0 -184
  208. package/esm/simul/SimulModule.js.map +0 -1
  209. package/esm/simul/reference-data/accounts.js +0 -25
  210. package/esm/simul/reference-data/accounts.js.map +0 -1
  211. package/esm/simul/reference-data/algos.js +0 -4
  212. package/esm/simul/reference-data/algos.js.map +0 -1
  213. package/esm/simul/reference-data/currencies.js +0 -4
  214. package/esm/simul/reference-data/currencies.js.map +0 -1
  215. package/esm/simul/reference-data/instruments-extended.js +0 -17
  216. package/esm/simul/reference-data/instruments-extended.js.map +0 -1
  217. package/esm/simul/reference-data/instruments.js +0 -82
  218. package/esm/simul/reference-data/instruments.js.map +0 -1
  219. package/esm/simul/reference-data/isin-generator/convert-string-to-base-ten-number.js +0 -4
  220. package/esm/simul/reference-data/isin-generator/convert-string-to-base-ten-number.js.map +0 -1
  221. package/esm/simul/reference-data/isin-generator/fixtures/alphabet.js +0 -29
  222. package/esm/simul/reference-data/isin-generator/fixtures/alphabet.js.map +0 -1
  223. package/esm/simul/reference-data/isin-generator/fixtures/alphanumeric-values.js +0 -7
  224. package/esm/simul/reference-data/isin-generator/fixtures/alphanumeric-values.js.map +0 -1
  225. package/esm/simul/reference-data/isin-generator/fixtures/base-ten-numbers.js +0 -15
  226. package/esm/simul/reference-data/isin-generator/fixtures/base-ten-numbers.js.map +0 -1
  227. package/esm/simul/reference-data/isin-generator/generate-cusip-check-code.js +0 -22
  228. package/esm/simul/reference-data/isin-generator/generate-cusip-check-code.js.map +0 -1
  229. package/esm/simul/reference-data/isin-generator/generate-cusip-without-check-code.js +0 -11
  230. package/esm/simul/reference-data/isin-generator/generate-cusip-without-check-code.js.map +0 -1
  231. package/esm/simul/reference-data/isin-generator/generate-cusip.js +0 -11
  232. package/esm/simul/reference-data/isin-generator/generate-cusip.js.map +0 -1
  233. package/esm/simul/reference-data/isin-generator/generate-random-alphanumeric.js +0 -6
  234. package/esm/simul/reference-data/isin-generator/generate-random-alphanumeric.js.map +0 -1
  235. package/esm/simul/reference-data/isin-generator/generate-random-base-ten-number.js +0 -4
  236. package/esm/simul/reference-data/isin-generator/generate-random-base-ten-number.js.map +0 -1
  237. package/esm/simul/reference-data/isin-generator/generate-random-string-of-alphanumeric-chars.js +0 -12
  238. package/esm/simul/reference-data/isin-generator/generate-random-string-of-alphanumeric-chars.js.map +0 -1
  239. package/esm/simul/reference-data/isin-generator/generate-random-string-of-base-ten-chars.js +0 -12
  240. package/esm/simul/reference-data/isin-generator/generate-random-string-of-base-ten-chars.js.map +0 -1
  241. package/esm/simul/reference-data/isin-generator/index.js +0 -293
  242. package/esm/simul/reference-data/isin-generator/index.js.map +0 -1
  243. package/esm/simul/reference-data/isin-generator/is-odd.js +0 -4
  244. package/esm/simul/reference-data/isin-generator/is-odd.js.map +0 -1
  245. package/esm/simul/reference-data/locations.js +0 -14
  246. package/esm/simul/reference-data/locations.js.map +0 -1
  247. package/esm/simul/reference-data/lotsizes.js +0 -26
  248. package/esm/simul/reference-data/lotsizes.js.map +0 -1
  249. package/esm/simul/reference-data/orderStatus.js +0 -4
  250. package/esm/simul/reference-data/orderStatus.js.map +0 -1
  251. package/esm/simul/reference-data/orders.js +0 -52
  252. package/esm/simul/reference-data/orders.js.map +0 -1
  253. package/esm/simul/reference-data/parent-child-orders.js +0 -141
  254. package/esm/simul/reference-data/parent-child-orders.js.map +0 -1
  255. package/esm/simul/reference-data/prices.js +0 -88
  256. package/esm/simul/reference-data/prices.js.map +0 -1
  257. package/esm/simul/reference-data/sides.js +0 -4
  258. package/esm/simul/reference-data/sides.js.map +0 -1
  259. package/esm/simul/simul-schemas.js +0 -156
  260. package/esm/simul/simul-schemas.js.map +0 -1
  261. package/esm/test/TestModule.js +0 -253
  262. package/esm/test/TestModule.js.map +0 -1
  263. package/esm/vuu-row-generator.js +0 -68
  264. package/esm/vuu-row-generator.js.map +0 -1
@@ -0,0 +1,635 @@
1
+ import { isAddRowRpcRequest, isBeginEditSessionRpcRequest, isCreateSessionTableRpcRequest, isDeleteSelectedRowsRpcRequest, isEditCellRpcRequest, isEndEditSessionRpcRequest, isRpcSuccess, isUndoRowChangeRpcRequest, uuid } from "@vuu-ui/vuu-utils";
2
+ import { Table, buildDataColumnMapFromSchema } from "../../Table.js";
3
+ import { TickingArrayDataSource } from "../../TickingArrayDataSource.js";
4
+ import { RuntimeVisualLink } from "../../RuntimeVisualLink.js";
5
+ import ModuleContainer from "./ModuleContainer.js";
6
+ import { sessionTableRow, sessionTableSchema } from "../../session-table-utils.js";
7
+ const assertUpdateIsValid = (schema, column, _data)=>{
8
+ const col = schema.columns.find((col)=>col.name === column);
9
+ if (col) ;
10
+ else throw Error(`schema for table ${schema.table.table} does not include column ${column}`);
11
+ };
12
+ class VuuModule {
13
+ #name;
14
+ #sessionTableMessageColumn;
15
+ #runtimeVisualLinks = new Map();
16
+ #sessionSourceTableMap = {};
17
+ #sessionTableMap = {};
18
+ #tableServices;
19
+ #subscriptionMap = new Map();
20
+ constructor(name, { sessionTableMessageColumn = "vuuMsg" } = {}){
21
+ this.#name = name;
22
+ this.#sessionTableMessageColumn = sessionTableMessageColumn;
23
+ ModuleContainer.register(this);
24
+ }
25
+ getTableSchema(tableName) {
26
+ return this.schemas[tableName] ?? this.#sessionTableMap[tableName]?.schema;
27
+ }
28
+ getTableList() {
29
+ return Object.keys(this.tables);
30
+ }
31
+ handlePostSubscribeActivities = ({ clientViewportId, tableSchema })=>{
32
+ const visualLinks = this.getVisualLinks(tableSchema.table.table);
33
+ const { dataSource } = this.getSubscriptionByViewport(clientViewportId);
34
+ requestAnimationFrame(()=>{
35
+ dataSource.links = visualLinks;
36
+ });
37
+ if (this.visualLinks && dataSource.tableSchema) {
38
+ const { table: { table: sourceTable } } = dataSource.tableSchema;
39
+ for (const [table, links] of Object.entries(this.visualLinks))if (links) {
40
+ const potentialTargets = links.filter((l)=>l.toTable === sourceTable);
41
+ if (potentialTargets.length) {
42
+ for (const subscriptions of this.#subscriptionMap.values())for (const { dataSource } of subscriptions)if (dataSource.tableSchema?.table.table === table) dataSource.links = this.getVisualLinks(table);
43
+ }
44
+ }
45
+ }
46
+ };
47
+ unregisterViewport = (viewportId)=>{
48
+ const { dataSource } = this.getSubscriptionByViewport(viewportId);
49
+ const tableName = dataSource.tableSchema?.table.table;
50
+ if (tableName) {
51
+ const subscriptionsForTable = this.#subscriptionMap.get(tableName);
52
+ if (subscriptionsForTable) {
53
+ for (const { viewportId: vp } of subscriptionsForTable)if (vp === viewportId) if (1 === subscriptionsForTable.length) this.#subscriptionMap.delete(tableName);
54
+ else this.#subscriptionMap.set(tableName, subscriptionsForTable.filter((s)=>s.viewportId !== viewportId));
55
+ }
56
+ }
57
+ for (const [tableName, subscriptions] of this.#subscriptionMap)if (subscriptions[0].viewportId.toString() === viewportId) this.#subscriptionMap.delete(tableName);
58
+ if (this.visualLinks && dataSource.tableSchema) {
59
+ const { table: { table: sourceTable } } = dataSource.tableSchema;
60
+ for (const [table, links] of Object.entries(this.visualLinks))if (links) {
61
+ const potentialTargets = links.filter((l)=>l.toTable === sourceTable);
62
+ if (potentialTargets.length) {
63
+ for (const subscriptions of this.#subscriptionMap.values())for (const { dataSource } of subscriptions)if (dataSource.tableSchema?.table.table === table) dataSource.links = this.getVisualLinks(table);
64
+ }
65
+ }
66
+ }
67
+ };
68
+ get name() {
69
+ return this.#name;
70
+ }
71
+ getSubscriptionByViewport(viewportId) {
72
+ for (const subscriptions of this.#subscriptionMap.values())for (const subscription of subscriptions)if (subscription.viewportId === viewportId) return subscription;
73
+ throw Error(`[VuuModule] getSubscriptionByViewport, no subscription found for ${viewportId}`);
74
+ }
75
+ getSubscribedDataSource(vpId) {
76
+ for (const subscriptions of this.#subscriptionMap.values())for (const { viewportId, dataSource } of subscriptions)if (viewportId === vpId) return dataSource;
77
+ throw Error(`getSubscribedDataSource #${vpId} not in subscriptionMap`);
78
+ }
79
+ getLinks = (subscriptionMap, vuuLinks)=>{
80
+ const visualLinks = [];
81
+ for(let i = 0; i < vuuLinks.length; i++){
82
+ const subscriptions = subscriptionMap.get(vuuLinks[i].toTable);
83
+ if (subscriptions) subscriptions.forEach(({ viewportId, dataSource: { status } })=>{
84
+ if ("suspended" !== status) {
85
+ const newLink = {
86
+ parentClientVpId: viewportId,
87
+ parentVpId: viewportId,
88
+ link: vuuLinks[i]
89
+ };
90
+ visualLinks.push(newLink);
91
+ }
92
+ });
93
+ }
94
+ return visualLinks;
95
+ };
96
+ visualLinkService = (message)=>new Promise((resolve)=>{
97
+ if ("CREATE_VISUAL_LINK" === message.type) {
98
+ const { childColumnName, childVpId, parentColumnName, parentVpId } = message;
99
+ const childDataSource = this.getSubscribedDataSource(childVpId);
100
+ const parentDataSource = this.getSubscribedDataSource(parentVpId);
101
+ const runtimeVisualLink = new RuntimeVisualLink(childDataSource, parentDataSource, childColumnName, parentColumnName);
102
+ this.#runtimeVisualLinks.set(childVpId, runtimeVisualLink);
103
+ resolve({
104
+ clientViewportId: childVpId,
105
+ colName: childColumnName,
106
+ parentColName: parentColumnName,
107
+ parentViewportId: parentVpId,
108
+ type: "vuu-link-created"
109
+ });
110
+ } else {
111
+ const runtimeVisualLink = this.#runtimeVisualLinks.get(message.childVpId);
112
+ if (runtimeVisualLink) {
113
+ runtimeVisualLink.remove();
114
+ this.#runtimeVisualLinks.delete(message.childVpId);
115
+ } else throw Error(`visualLinkService no visual link found for viewport #${message.childVpId}`);
116
+ resolve();
117
+ }
118
+ });
119
+ getVisualLinks = (tableName)=>{
120
+ const linksForTable = this.visualLinks?.[tableName];
121
+ return void 0 === linksForTable ? void 0 : this.getLinks(this.#subscriptionMap, linksForTable);
122
+ };
123
+ createDataSource = (tableName, viewport, config)=>{
124
+ const columnDescriptors = this.getColumnDescriptors(tableName);
125
+ const table = this.tables[tableName];
126
+ const sessionTable = this.#sessionTableMap[tableName];
127
+ const vuuModule = this;
128
+ const dataSource = new TickingArrayDataSource({
129
+ ...config,
130
+ columnDescriptors,
131
+ getVisualLinks: this.getVisualLinks,
132
+ keyColumn: void 0 === this.schemas[tableName] ? this.#sessionTableMap[tableName].schema.key : this.schemas[tableName].key,
133
+ table: table || sessionTable,
134
+ menu: this.menus?.[tableName],
135
+ rpcServices: this.getServices(tableName),
136
+ rpcMenuServices: this.getMenuServices(tableName),
137
+ viewport,
138
+ visualLinkService: this.visualLinkService,
139
+ vuuModule
140
+ });
141
+ dataSource.on("subscribed", this.handlePostSubscribeActivities);
142
+ dataSource.on("unsubscribed", this.unregisterViewport);
143
+ const existingSubscriptions = this.#subscriptionMap.get(tableName);
144
+ const subscription = {
145
+ viewportId: dataSource.viewport,
146
+ dataSource,
147
+ sessionTableName: sessionTable ? tableName : void 0,
148
+ sourceTableName: this.#sessionSourceTableMap[tableName]
149
+ };
150
+ if (existingSubscriptions) existingSubscriptions.push(subscription);
151
+ else this.#subscriptionMap.set(tableName, [
152
+ subscription
153
+ ]);
154
+ return dataSource;
155
+ };
156
+ getServices(tableName) {
157
+ const tableServices = this.services?.[tableName];
158
+ if (Array.isArray(tableServices)) return this.#moduleServices.concat(tableServices);
159
+ return this.#moduleServices;
160
+ }
161
+ getMenuServices(tableName) {
162
+ const tableServices = this.menuServices?.[tableName];
163
+ if (Array.isArray(tableServices)) return this.#moduleMenuServices.concat(tableServices);
164
+ return this.#moduleMenuServices;
165
+ }
166
+ get sessionTableMap() {
167
+ return this.#sessionTableMap;
168
+ }
169
+ getSessionTable(sessionTableName, throwIfNotFound = true) {
170
+ const sessionTable = this.#sessionTableMap[sessionTableName];
171
+ if (sessionTable) return sessionTable;
172
+ if (throwIfNotFound) throw Error(`getSessionTable: no session table with name ${sessionTableName}`);
173
+ }
174
+ deleteRow = async (rpcRequest)=>{
175
+ if ("VIEWPORT_CONTEXT" === rpcRequest.context.type) {
176
+ const { viewPortId } = rpcRequest.context;
177
+ const { key, mode = "hard" } = rpcRequest.params;
178
+ const sessionTable = this.getSessionTable(viewPortId, false);
179
+ if (sessionTable) {
180
+ if ("soft" === mode) sessionTable.update(key, "vuu_action", "deleteRow");
181
+ else sessionTable.delete(key);
182
+ return {
183
+ type: "SUCCESS_RESULT",
184
+ data: void 0
185
+ };
186
+ }
187
+ {
188
+ const { dataSource } = this.getSubscriptionByViewport(viewPortId);
189
+ if (dataSource.table) {
190
+ const table = this.tables[dataSource.table.table];
191
+ if (table) {
192
+ if ("soft" === mode) table.update(key, this.#sessionTableMessageColumn, "SOFT_DELETED");
193
+ else table.delete(key);
194
+ return {
195
+ type: "SUCCESS_RESULT",
196
+ data: void 0
197
+ };
198
+ }
199
+ }
200
+ }
201
+ }
202
+ return {
203
+ type: "ERROR_RESULT",
204
+ errorMessage: "something went wrong"
205
+ };
206
+ };
207
+ deleteSelectedRows = async (rpcRequest)=>{
208
+ if (isDeleteSelectedRowsRpcRequest(rpcRequest)) {
209
+ const { viewPortId } = rpcRequest.context;
210
+ const { mode = "soft" } = rpcRequest.params;
211
+ const sessionTable = this.getSessionTable(viewPortId, false);
212
+ if (sessionTable) {
213
+ const { dataSource } = this.getSubscriptionByViewport(viewPortId);
214
+ const selectedRowIds = dataSource.getSelectedRowIds();
215
+ const deletedKeys = [];
216
+ if (selectedRowIds.length > 0) {
217
+ for (const key of selectedRowIds){
218
+ if ("soft" === mode) sessionTable.update(key, "vuu_action", "deleteRow");
219
+ else sessionTable.delete(key);
220
+ deletedKeys.push(key);
221
+ }
222
+ dataSource.select?.({
223
+ type: "DESELECT_ALL"
224
+ });
225
+ }
226
+ return {
227
+ type: "SUCCESS_RESULT",
228
+ data: {
229
+ deletedKeys
230
+ }
231
+ };
232
+ }
233
+ return {
234
+ type: "ERROR_RESULT",
235
+ errorMessage: `deleteSelectedRows: no active session table for viewport ${viewPortId}`
236
+ };
237
+ }
238
+ return {
239
+ type: "ERROR_RESULT",
240
+ errorMessage: "deleteSelectedRows: invalid rpc request"
241
+ };
242
+ };
243
+ undoRowChange = async (rpcRequest)=>{
244
+ if (isUndoRowChangeRpcRequest(rpcRequest)) {
245
+ const { viewPortId } = rpcRequest.context;
246
+ const { key } = rpcRequest.params;
247
+ const sessionTable = this.getSessionTable(viewPortId, false);
248
+ if (sessionTable) {
249
+ const subscription = this.getSubscriptionByViewport(viewPortId);
250
+ const { dataSource } = subscription;
251
+ const sourceTableName = subscription.sourceTableName ?? dataSource.table?.table;
252
+ const sourceTable = this.tables[sourceTableName];
253
+ if (!sourceTable) return {
254
+ type: "ERROR_RESULT",
255
+ errorMessage: `undoRowChange: source table not found for viewport ${viewPortId}`
256
+ };
257
+ const sessionRow = sessionTable.findByKey(key);
258
+ if (!sessionRow) return {
259
+ type: "ERROR_RESULT",
260
+ errorMessage: `undoRowChange: session row not found for key ${key}`
261
+ };
262
+ const action = sessionRow[sessionTable.map.vuu_action];
263
+ if ("addRow" === action) {
264
+ sessionTable.delete(key);
265
+ return {
266
+ type: "SUCCESS_RESULT",
267
+ data: {
268
+ wasInsertedRow: true
269
+ }
270
+ };
271
+ }
272
+ if ("deleteRow" === action || "editCell" === action) {
273
+ const sourceRow = sourceTable.findByKey(key);
274
+ if (!sourceRow) return {
275
+ type: "ERROR_RESULT",
276
+ errorMessage: `undoRowChange: source row not found for key ${key}`
277
+ };
278
+ const restoredRow = sessionRow.slice();
279
+ for (const column of sourceTable.schema.columns)restoredRow[sessionTable.map[column.name]] = sourceRow[sourceTable.map[column.name]];
280
+ sessionTable.updateRow(restoredRow);
281
+ sessionTable.update(key, "vuu_action", "");
282
+ }
283
+ return {
284
+ type: "SUCCESS_RESULT",
285
+ data: void 0
286
+ };
287
+ }
288
+ return {
289
+ type: "ERROR_RESULT",
290
+ errorMessage: `undoRowChange: no active session table for viewport ${viewPortId}`
291
+ };
292
+ }
293
+ return {
294
+ type: "ERROR_RESULT",
295
+ errorMessage: "undoRowChange: invalid rpc request"
296
+ };
297
+ };
298
+ getColumnDescriptors(tableName) {
299
+ const schema = this.schemas[tableName] || this.getSessionTable(tableName)?.schema;
300
+ if (schema) return schema.columns;
301
+ throw Error(` no schema found for module ${this.#name} table ${tableName}`);
302
+ }
303
+ editCell = async (rpcRequest)=>{
304
+ if (isEditCellRpcRequest(rpcRequest)) {
305
+ const { viewPortId } = rpcRequest.context;
306
+ const { column, data, key } = rpcRequest.params;
307
+ const sessionTable = this.#sessionTableMap[viewPortId];
308
+ let targetTable = sessionTable;
309
+ if (!targetTable) {
310
+ const { dataSource } = this.getSubscriptionByViewport(viewPortId);
311
+ if (dataSource.table) targetTable = this.tables[dataSource.table.table];
312
+ }
313
+ if (targetTable) try {
314
+ const sessionRow = sessionTable?.findByKey(key);
315
+ if (sessionRow?.[sessionTable.map.vuu_action] === "deleteRow") throw Error("editCell: cannot edit a deleted row");
316
+ assertUpdateIsValid(targetTable.schema, column, data);
317
+ targetTable.update(key, column, data);
318
+ if (sessionTable && sessionTable.findByKey(key)?.[sessionTable.map.vuu_action] !== "addRow") sessionTable.update(key, "vuu_action", "editCell");
319
+ return {
320
+ type: "SUCCESS_RESULT",
321
+ data: void 0
322
+ };
323
+ } catch (e) {
324
+ const { message } = e;
325
+ return {
326
+ type: "ERROR_RESULT",
327
+ errorMessage: message
328
+ };
329
+ }
330
+ throw Error("[VuuModule] editCell unable to find table for dataSource");
331
+ }
332
+ throw Error("[VuuModule] editCell invalid rpc type");
333
+ };
334
+ beginEditSessionMenuHandler = async ({ rpcName, type, vpId })=>{
335
+ if ("VIEW_PORT_MENUS_SELECT_RPC" !== type) return {
336
+ error: "no can do",
337
+ rpcName,
338
+ type: "VIEW_PORT_MENU_REJ",
339
+ vpId
340
+ };
341
+ {
342
+ const result = await this.beginEditSession({
343
+ context: {
344
+ type: "VIEWPORT_CONTEXT",
345
+ viewPortId: vpId
346
+ },
347
+ params: {
348
+ editSessionMode: "selected-rows"
349
+ },
350
+ rpcName,
351
+ type: "RPC_REQUEST"
352
+ });
353
+ if (!isRpcSuccess(result)) return {
354
+ error: result.errorMessage,
355
+ rpcName,
356
+ type: "VIEW_PORT_MENU_REJ",
357
+ vpId
358
+ };
359
+ {
360
+ const { table } = result.data;
361
+ return {
362
+ type: "VIEW_PORT_MENU_RESP",
363
+ rpcName,
364
+ action: {
365
+ renderComponent: "grid",
366
+ type: "OPEN_DIALOG_ACTION",
367
+ table
368
+ },
369
+ vpId
370
+ };
371
+ }
372
+ }
373
+ };
374
+ createSessionTableService = async (rpcRequest)=>{
375
+ if (isCreateSessionTableRpcRequest(rpcRequest)) {
376
+ const { viewPortId } = rpcRequest.context;
377
+ const { copyOption } = rpcRequest.params;
378
+ const subscription = this.getSubscriptionByViewport(viewPortId);
379
+ const { dataSource } = subscription;
380
+ const { table: vuuTable } = dataSource;
381
+ if (vuuTable) {
382
+ const sourceTable = this.tables[vuuTable.table];
383
+ if (sourceTable) {
384
+ const sessionTableName = `session-${uuid()}`;
385
+ try {
386
+ const sessionTable = this.createSessionTable(sourceTable, sessionTableName, copyOption, dataSource);
387
+ this.#sessionTableMap[sessionTableName] = sessionTable;
388
+ this.#sessionSourceTableMap[sessionTableName] = vuuTable.table;
389
+ subscription.sessionTableName = sessionTableName;
390
+ return {
391
+ data: {
392
+ table: {
393
+ module: vuuTable.module,
394
+ table: sessionTableName
395
+ }
396
+ },
397
+ type: "SUCCESS_RESULT"
398
+ };
399
+ } catch (e) {
400
+ return {
401
+ type: "ERROR_RESULT",
402
+ errorMessage: e.message
403
+ };
404
+ }
405
+ }
406
+ }
407
+ }
408
+ return {
409
+ type: "ERROR_RESULT",
410
+ errorMessage: "createSessionTable: invalid rpc request"
411
+ };
412
+ };
413
+ beginEditSession = async (rpcRequest)=>{
414
+ if (isBeginEditSessionRpcRequest(rpcRequest)) {
415
+ const { viewPortId } = rpcRequest.context;
416
+ const { editSessionMode = "inline-all-rows" } = rpcRequest.params;
417
+ const subscription = this.getSubscriptionByViewport(viewPortId);
418
+ const { dataSource } = subscription;
419
+ const { table: vuuTable } = dataSource;
420
+ if (vuuTable) {
421
+ const sourceTable = this.tables[vuuTable.table];
422
+ if (sourceTable) {
423
+ const sessionTableName = `session-${uuid()}`;
424
+ try {
425
+ const sessionTable = this.createSessionTable(sourceTable, sessionTableName, editSessionMode, dataSource);
426
+ this.#sessionTableMap[sessionTableName] = sessionTable;
427
+ this.#sessionSourceTableMap[sessionTableName] = vuuTable.table;
428
+ subscription.sessionTableName = sessionTableName;
429
+ return {
430
+ data: {
431
+ renderComponent: "inline-form",
432
+ table: {
433
+ module: vuuTable.module,
434
+ table: sessionTableName
435
+ }
436
+ },
437
+ type: "SUCCESS_RESULT"
438
+ };
439
+ } catch (e) {
440
+ return {
441
+ type: "ERROR_RESULT",
442
+ errorMessage: e.message
443
+ };
444
+ }
445
+ }
446
+ }
447
+ } else throw Error("[VuuModule] endEditSession invalid rpc type");
448
+ return {
449
+ type: "ERROR_RESULT",
450
+ errorMessage: "not implemented yet"
451
+ };
452
+ };
453
+ addRow = async (rpcRequest)=>{
454
+ if (isAddRowRpcRequest(rpcRequest)) {
455
+ const { viewPortId } = rpcRequest.context;
456
+ const subscription = this.getSubscriptionByViewport(viewPortId);
457
+ const sessionTableName = subscription.sessionTableName ?? viewPortId;
458
+ const sessionTable = this.#sessionTableMap[sessionTableName];
459
+ if (!sessionTable) return {
460
+ type: "ERROR_RESULT",
461
+ errorMessage: `addRow: no active session table for viewport ${viewPortId}`
462
+ };
463
+ const { data } = rpcRequest.params;
464
+ const keyColumn = sessionTable.schema.key;
465
+ const rowKey = data[keyColumn] ?? uuid();
466
+ const rowData = {
467
+ ...data,
468
+ [keyColumn]: rowKey
469
+ };
470
+ const columnMap = sessionTable.map;
471
+ const columnCount = Object.keys(columnMap).length;
472
+ const row = new Array(columnCount).fill("");
473
+ row[columnMap.vuu_action] = "addRow";
474
+ for (const [col, idx] of Object.entries(columnMap))if (void 0 !== rowData[col]) row[idx] = rowData[col];
475
+ sessionTable.insert(row);
476
+ return {
477
+ type: "SUCCESS_RESULT",
478
+ data: void 0
479
+ };
480
+ }
481
+ return {
482
+ type: "ERROR_RESULT",
483
+ errorMessage: "addRow: invalid rpc context"
484
+ };
485
+ };
486
+ endEditSession = async (rpcRequest)=>{
487
+ if (isEndEditSessionRpcRequest(rpcRequest)) {
488
+ const { viewPortId } = rpcRequest.context;
489
+ const subscription = this.getSubscriptionByViewport(viewPortId);
490
+ const sessionTableName = subscription.sessionTableName ?? viewPortId;
491
+ const sessionTable = this.#sessionTableMap[sessionTableName];
492
+ const { dataSource } = subscription;
493
+ if (dataSource.table) {
494
+ const sourceTableName = subscription.sourceTableName ?? dataSource.table.table;
495
+ const sourceTable = this.tables[sourceTableName];
496
+ if (true !== rpcRequest.params.save) return {
497
+ type: "SUCCESS_RESULT",
498
+ data: void 0
499
+ };
500
+ {
501
+ let rejectedCount = 0;
502
+ const vuuMsgIdx = sessionTable.map[this.#sessionTableMessageColumn];
503
+ const actionIdx = sessionTable.map.vuu_action;
504
+ const sessionTimestampIdx = sessionTable.map.vuuUpdatedTimestamp;
505
+ const sourceTimestampIdx = sourceTable.map.vuuUpdatedTimestamp;
506
+ const sourceColumns = sourceTable.schema.columns;
507
+ for(let i = 0; i < sessionTable.data.length; i++){
508
+ const sessionRow = sessionTable.data[i];
509
+ const key = String(sessionRow[sessionTable.map[sourceTable.schema.key]]);
510
+ const currentRow = sourceTable.findByKey(key);
511
+ const action = sessionRow[actionIdx];
512
+ if ("deleteRow" === action) {
513
+ if (currentRow) {
514
+ const sessionTimestamp = sessionRow[sessionTimestampIdx];
515
+ const sourceTimestamp = currentRow[sourceTimestampIdx];
516
+ if ("number" == typeof sessionTimestamp && "number" == typeof sourceTimestamp && sourceTimestamp > sessionTimestamp) {
517
+ rejectedCount += 1;
518
+ sessionTable.update(key, this.#sessionTableMessageColumn, "stale delete");
519
+ } else sourceTable.delete(key);
520
+ }
521
+ continue;
522
+ }
523
+ if (!sessionRow[vuuMsgIdx]) {
524
+ if ("editCell" === action && currentRow) for (const column of sourceColumns){
525
+ const value = sessionRow[sessionTable.map[column.name]];
526
+ if (currentRow[sourceTable.map[column.name]] !== value) sourceTable.update(key, column.name, value);
527
+ }
528
+ else if ("addRow" === action && !currentRow) sourceTable.insert(sourceColumns.map((column)=>sessionRow[sessionTable.map[column.name]]));
529
+ }
530
+ }
531
+ if (rejectedCount > 0) return {
532
+ errorMessage: "stale update",
533
+ type: "ERROR_RESULT"
534
+ };
535
+ return {
536
+ type: "SUCCESS_RESULT",
537
+ data: void 0
538
+ };
539
+ }
540
+ }
541
+ throw Error("[VuuModule], exitEditMode");
542
+ }
543
+ throw Error("[VuuModule] endEditSession invalid rpc type");
544
+ };
545
+ applyBulkEdits = async (rpcRequest)=>{
546
+ if ("VIEWPORT_CONTEXT" === rpcRequest.context.type) {
547
+ const { viewPortId } = rpcRequest.context;
548
+ const sessionTable = this.getSessionTable(viewPortId);
549
+ for(let i = 0; i < sessionTable.data.length; i++){
550
+ const newRow = sessionTable.data[i];
551
+ const { column, value } = rpcRequest.params;
552
+ const keyIndex = sessionTable.map[sessionTable.schema.key];
553
+ sessionTable.update(String(newRow[keyIndex]), column, value);
554
+ }
555
+ return {
556
+ type: "SUCCESS_RESULT",
557
+ data: void 0
558
+ };
559
+ }
560
+ throw Error("[VuuModule] applyBulkEdits invalid rpc type");
561
+ };
562
+ createSessionTable(sourceTable, sessionTableName, editSessionMode, dataSource) {
563
+ if ("All" === editSessionMode || editSessionMode.endsWith("all-rows")) return this.createSessionTableWithAllRows(sourceTable, sessionTableName);
564
+ if ("Selected" === editSessionMode || "selected-rows" === editSessionMode) return this.createSessionTableFromSelectedRows(sourceTable, sessionTableName, dataSource);
565
+ if ("Empty" === editSessionMode || "empty-session-table" === editSessionMode) return this.createEmptySessionTable(sourceTable, sessionTableName);
566
+ throw Error(`[VuuModule] createSessionTable, invalid editSessionMode ${editSessionMode}`);
567
+ }
568
+ createSessionTableWithAllRows({ data, schema }, _sessionTableName) {
569
+ const sessionSchema = sessionTableSchema(schema);
570
+ return new Table(sessionSchema, data.map((row)=>sessionTableRow(row, schema)), buildDataColumnMapFromSchema(sessionSchema));
571
+ }
572
+ createEmptySessionTable({ schema }, sessionTableName) {
573
+ const sessionSchema = sessionTableSchema({
574
+ ...schema,
575
+ table: {
576
+ ...schema.table,
577
+ table: sessionTableName
578
+ }
579
+ });
580
+ return new Table(sessionSchema, [], buildDataColumnMapFromSchema(sessionSchema));
581
+ }
582
+ createSessionTableFromSelectedRows({ data, map, schema }, sessionTableName, dataSource) {
583
+ const selectedRowIds = dataSource.getSelectedRowIds();
584
+ const keyIndex = map[schema.key];
585
+ const sessionData = [];
586
+ for(let i = 0; i < selectedRowIds.length; i++)for(let j = 0; j < data.length; j++)if (data[j][keyIndex] === selectedRowIds[i]) sessionData.push(sessionTableRow(data[j], schema));
587
+ const sessionSchema = sessionTableSchema(schema);
588
+ return new Table(sessionSchema, sessionData, buildDataColumnMapFromSchema(sessionSchema));
589
+ }
590
+ #moduleServices = [
591
+ {
592
+ rpcName: "addRow",
593
+ service: this.addRow
594
+ },
595
+ {
596
+ rpcName: "VP_BULK_EDIT_COLUMN_CELLS_RPC",
597
+ service: this.applyBulkEdits
598
+ },
599
+ {
600
+ rpcName: "createSessionTable",
601
+ service: this.createSessionTableService
602
+ },
603
+ {
604
+ rpcName: "beginEditSession",
605
+ service: this.beginEditSession
606
+ },
607
+ {
608
+ rpcName: "deleteRow",
609
+ service: this.deleteRow
610
+ },
611
+ {
612
+ rpcName: "deleteSelectedRows",
613
+ service: this.deleteSelectedRows
614
+ },
615
+ {
616
+ rpcName: "endEditSession",
617
+ service: this.endEditSession
618
+ },
619
+ {
620
+ rpcName: "editCell",
621
+ service: this.editCell
622
+ },
623
+ {
624
+ rpcName: "undoRowChange",
625
+ service: this.undoRowChange
626
+ }
627
+ ];
628
+ #moduleMenuServices = [
629
+ {
630
+ rpcName: "beginEditSession",
631
+ service: this.beginEditSessionMenuHandler
632
+ }
633
+ ];
634
+ }
635
+ export { VuuModule };