@speckle/objectloader2 2.25.4 → 2.25.8

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 (419) hide show
  1. package/dist/commonjs/{operations → core}/interfaces.d.ts +2 -5
  2. package/dist/commonjs/core/interfaces.d.ts.map +1 -0
  3. package/dist/commonjs/core/interfaces.js.map +1 -0
  4. package/dist/{esm/operations → commonjs/core}/objectLoader2.d.ts +1 -1
  5. package/dist/commonjs/core/objectLoader2.d.ts.map +1 -0
  6. package/dist/commonjs/core/objectLoader2.js +128 -0
  7. package/dist/commonjs/core/objectLoader2.js.map +1 -0
  8. package/dist/commonjs/core/objectLoader2Factory.d.ts +27 -0
  9. package/dist/commonjs/core/objectLoader2Factory.d.ts.map +1 -0
  10. package/dist/commonjs/core/objectLoader2Factory.js +74 -0
  11. package/dist/commonjs/core/objectLoader2Factory.js.map +1 -0
  12. package/dist/{esm/operations → commonjs/core}/options.d.ts +2 -1
  13. package/dist/commonjs/core/options.d.ts.map +1 -0
  14. package/dist/commonjs/{operations → core}/options.js.map +1 -1
  15. package/dist/commonjs/core/stages/ItemStore.d.ts +37 -0
  16. package/dist/commonjs/core/stages/ItemStore.d.ts.map +1 -0
  17. package/dist/commonjs/core/stages/ItemStore.js +167 -0
  18. package/dist/commonjs/core/stages/ItemStore.js.map +1 -0
  19. package/dist/commonjs/core/stages/cacheReader.d.ts +18 -0
  20. package/dist/commonjs/core/stages/cacheReader.d.ts.map +1 -0
  21. package/dist/commonjs/core/stages/cacheReader.js +72 -0
  22. package/dist/commonjs/core/stages/cacheReader.js.map +1 -0
  23. package/dist/commonjs/core/stages/cacheWriter.d.ts +15 -0
  24. package/dist/commonjs/core/stages/cacheWriter.d.ts.map +1 -0
  25. package/dist/commonjs/core/stages/cacheWriter.js +50 -0
  26. package/dist/commonjs/core/stages/cacheWriter.js.map +1 -0
  27. package/dist/commonjs/{operations/databases → core/stages}/indexedDatabase.d.ts +2 -7
  28. package/dist/commonjs/core/stages/indexedDatabase.d.ts.map +1 -0
  29. package/dist/commonjs/core/stages/indexedDatabase.js +31 -0
  30. package/dist/commonjs/core/stages/indexedDatabase.js.map +1 -0
  31. package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts +13 -0
  32. package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts.map +1 -0
  33. package/dist/commonjs/{operations/databases → core/stages/memory}/memoryDatabase.js +4 -8
  34. package/dist/commonjs/core/stages/memory/memoryDatabase.js.map +1 -0
  35. package/dist/commonjs/{operations/downloaders → core/stages/memory}/memoryDownloader.d.ts +3 -3
  36. package/dist/commonjs/core/stages/memory/memoryDownloader.d.ts.map +1 -0
  37. package/dist/commonjs/{operations/downloaders → core/stages/memory}/memoryDownloader.js +1 -1
  38. package/dist/commonjs/core/stages/memory/memoryDownloader.js.map +1 -0
  39. package/dist/{esm/operations/downloaders → commonjs/core/stages}/serverDownloader.d.ts +4 -5
  40. package/dist/commonjs/core/stages/serverDownloader.d.ts.map +1 -0
  41. package/dist/commonjs/{operations/downloaders → core/stages}/serverDownloader.js +82 -32
  42. package/dist/commonjs/core/stages/serverDownloader.js.map +1 -0
  43. package/dist/commonjs/core/traverser.d.ts.map +1 -0
  44. package/dist/commonjs/{operations → core}/traverser.js +7 -7
  45. package/dist/commonjs/core/traverser.js.map +1 -0
  46. package/dist/commonjs/deferment/MemoryCache.d.ts +35 -0
  47. package/dist/commonjs/deferment/MemoryCache.d.ts.map +1 -0
  48. package/dist/commonjs/deferment/MemoryCache.js +162 -0
  49. package/dist/commonjs/deferment/MemoryCache.js.map +1 -0
  50. package/dist/commonjs/deferment/MemoryCache.test.d.ts +2 -0
  51. package/dist/commonjs/deferment/MemoryCache.test.d.ts.map +1 -0
  52. package/dist/commonjs/deferment/MemoryCache.test.js +153 -0
  53. package/dist/commonjs/deferment/MemoryCache.test.js.map +1 -0
  54. package/dist/commonjs/deferment/defermentManager.d.ts +16 -0
  55. package/dist/commonjs/deferment/defermentManager.d.ts.map +1 -0
  56. package/dist/commonjs/deferment/defermentManager.js +58 -0
  57. package/dist/commonjs/deferment/defermentManager.js.map +1 -0
  58. package/dist/commonjs/deferment/defermentManager.test.d.ts +2 -0
  59. package/dist/commonjs/deferment/defermentManager.test.d.ts.map +1 -0
  60. package/dist/commonjs/deferment/defermentManager.test.js +188 -0
  61. package/dist/commonjs/deferment/defermentManager.test.js.map +1 -0
  62. package/dist/commonjs/deferment/deferredBase.d.ts +12 -0
  63. package/dist/commonjs/deferment/deferredBase.d.ts.map +1 -0
  64. package/dist/commonjs/deferment/deferredBase.js +27 -0
  65. package/dist/commonjs/deferment/deferredBase.js.map +1 -0
  66. package/dist/commonjs/index.d.ts +3 -3
  67. package/dist/commonjs/index.d.ts.map +1 -1
  68. package/dist/commonjs/index.js +6 -5
  69. package/dist/commonjs/index.js.map +1 -1
  70. package/dist/commonjs/{helpers → queues}/aggregateQueue.d.ts +2 -1
  71. package/dist/commonjs/queues/aggregateQueue.d.ts.map +1 -0
  72. package/dist/commonjs/{helpers → queues}/aggregateQueue.js +4 -0
  73. package/dist/commonjs/queues/aggregateQueue.js.map +1 -0
  74. package/dist/{esm/helpers → commonjs/queues}/asyncGeneratorQueue.d.ts +1 -1
  75. package/dist/commonjs/queues/asyncGeneratorQueue.d.ts.map +1 -0
  76. package/dist/commonjs/{helpers → queues}/asyncGeneratorQueue.js +2 -1
  77. package/dist/commonjs/queues/asyncGeneratorQueue.js.map +1 -0
  78. package/dist/{esm/helpers → commonjs/queues}/batchedPool.d.ts +2 -1
  79. package/dist/commonjs/queues/batchedPool.d.ts.map +1 -0
  80. package/dist/commonjs/queues/batchedPool.js.map +1 -0
  81. package/dist/{esm/helpers → commonjs/queues}/batchingQueue.d.ts +4 -1
  82. package/dist/commonjs/queues/batchingQueue.d.ts.map +1 -0
  83. package/dist/commonjs/queues/batchingQueue.dispose.test.d.ts +2 -0
  84. package/dist/commonjs/queues/batchingQueue.dispose.test.d.ts.map +1 -0
  85. package/dist/commonjs/queues/batchingQueue.dispose.test.js +64 -0
  86. package/dist/commonjs/queues/batchingQueue.dispose.test.js.map +1 -0
  87. package/dist/commonjs/queues/batchingQueue.js +123 -0
  88. package/dist/commonjs/queues/batchingQueue.js.map +1 -0
  89. package/dist/commonjs/queues/batchingQueue.test.d.ts +2 -0
  90. package/dist/commonjs/queues/batchingQueue.test.d.ts.map +1 -0
  91. package/dist/commonjs/queues/batchingQueue.test.js +138 -0
  92. package/dist/commonjs/queues/batchingQueue.test.js.map +1 -0
  93. package/dist/{esm/helpers → commonjs/queues}/bufferQueue.d.ts +1 -0
  94. package/dist/commonjs/queues/bufferQueue.d.ts.map +1 -0
  95. package/dist/commonjs/{helpers → queues}/bufferQueue.js +3 -0
  96. package/dist/commonjs/queues/bufferQueue.js.map +1 -0
  97. package/dist/commonjs/{helpers → queues}/keyedQueue.d.ts +1 -0
  98. package/dist/commonjs/queues/keyedQueue.d.ts.map +1 -0
  99. package/dist/commonjs/{helpers → queues}/keyedQueue.js +11 -0
  100. package/dist/commonjs/queues/keyedQueue.js.map +1 -0
  101. package/dist/commonjs/queues/queue.d.ts +5 -0
  102. package/dist/commonjs/queues/queue.d.ts.map +1 -0
  103. package/dist/commonjs/{helpers → queues}/queue.js.map +1 -1
  104. package/dist/commonjs/types/functions.d.ts +21 -0
  105. package/dist/commonjs/types/functions.d.ts.map +1 -0
  106. package/dist/commonjs/types/functions.js +92 -0
  107. package/dist/commonjs/types/functions.js.map +1 -0
  108. package/dist/commonjs/types/types.d.ts +1 -7
  109. package/dist/commonjs/types/types.d.ts.map +1 -1
  110. package/dist/commonjs/types/types.js +0 -36
  111. package/dist/commonjs/types/types.js.map +1 -1
  112. package/dist/esm/{operations → core}/interfaces.d.ts +2 -5
  113. package/dist/esm/core/interfaces.d.ts.map +1 -0
  114. package/dist/esm/core/interfaces.js.map +1 -0
  115. package/dist/{commonjs/operations → esm/core}/objectLoader2.d.ts +1 -1
  116. package/dist/esm/core/objectLoader2.d.ts.map +1 -0
  117. package/dist/esm/core/objectLoader2.js +121 -0
  118. package/dist/esm/core/objectLoader2.js.map +1 -0
  119. package/dist/esm/core/objectLoader2Factory.d.ts +27 -0
  120. package/dist/esm/core/objectLoader2Factory.d.ts.map +1 -0
  121. package/dist/esm/core/objectLoader2Factory.js +67 -0
  122. package/dist/esm/core/objectLoader2Factory.js.map +1 -0
  123. package/dist/{commonjs/operations → esm/core}/options.d.ts +2 -1
  124. package/dist/esm/core/options.d.ts.map +1 -0
  125. package/dist/esm/{operations → core}/options.js.map +1 -1
  126. package/dist/esm/core/stages/ItemStore.d.ts +37 -0
  127. package/dist/esm/core/stages/ItemStore.d.ts.map +1 -0
  128. package/dist/esm/core/stages/ItemStore.js +163 -0
  129. package/dist/esm/core/stages/ItemStore.js.map +1 -0
  130. package/dist/esm/core/stages/cacheReader.d.ts +18 -0
  131. package/dist/esm/core/stages/cacheReader.d.ts.map +1 -0
  132. package/dist/esm/core/stages/cacheReader.js +65 -0
  133. package/dist/esm/core/stages/cacheReader.js.map +1 -0
  134. package/dist/esm/core/stages/cacheWriter.d.ts +15 -0
  135. package/dist/esm/core/stages/cacheWriter.d.ts.map +1 -0
  136. package/dist/esm/core/stages/cacheWriter.js +43 -0
  137. package/dist/esm/core/stages/cacheWriter.js.map +1 -0
  138. package/dist/esm/{operations/databases → core/stages}/indexedDatabase.d.ts +2 -7
  139. package/dist/esm/core/stages/indexedDatabase.d.ts.map +1 -0
  140. package/dist/esm/core/stages/indexedDatabase.js +28 -0
  141. package/dist/esm/core/stages/indexedDatabase.js.map +1 -0
  142. package/dist/esm/core/stages/memory/memoryDatabase.d.ts +13 -0
  143. package/dist/esm/core/stages/memory/memoryDatabase.d.ts.map +1 -0
  144. package/dist/esm/{operations/databases → core/stages/memory}/memoryDatabase.js +4 -8
  145. package/dist/esm/core/stages/memory/memoryDatabase.js.map +1 -0
  146. package/dist/esm/{operations/downloaders → core/stages/memory}/memoryDownloader.d.ts +3 -3
  147. package/dist/esm/core/stages/memory/memoryDownloader.d.ts.map +1 -0
  148. package/dist/esm/{operations/downloaders → core/stages/memory}/memoryDownloader.js +1 -1
  149. package/dist/esm/core/stages/memory/memoryDownloader.js.map +1 -0
  150. package/dist/{commonjs/operations/downloaders → esm/core/stages}/serverDownloader.d.ts +4 -5
  151. package/dist/esm/core/stages/serverDownloader.d.ts.map +1 -0
  152. package/dist/esm/{operations/downloaders → core/stages}/serverDownloader.js +81 -31
  153. package/dist/esm/core/stages/serverDownloader.js.map +1 -0
  154. package/dist/esm/core/traverser.d.ts.map +1 -0
  155. package/dist/esm/{operations → core}/traverser.js +1 -1
  156. package/dist/esm/core/traverser.js.map +1 -0
  157. package/dist/esm/deferment/MemoryCache.d.ts +35 -0
  158. package/dist/esm/deferment/MemoryCache.d.ts.map +1 -0
  159. package/dist/esm/deferment/MemoryCache.js +157 -0
  160. package/dist/esm/deferment/MemoryCache.js.map +1 -0
  161. package/dist/esm/deferment/MemoryCache.test.d.ts +2 -0
  162. package/dist/esm/deferment/MemoryCache.test.d.ts.map +1 -0
  163. package/dist/esm/deferment/MemoryCache.test.js +151 -0
  164. package/dist/esm/deferment/MemoryCache.test.js.map +1 -0
  165. package/dist/esm/deferment/defermentManager.d.ts +16 -0
  166. package/dist/esm/deferment/defermentManager.d.ts.map +1 -0
  167. package/dist/esm/deferment/defermentManager.js +54 -0
  168. package/dist/esm/deferment/defermentManager.js.map +1 -0
  169. package/dist/esm/deferment/defermentManager.test.d.ts +2 -0
  170. package/dist/esm/deferment/defermentManager.test.d.ts.map +1 -0
  171. package/dist/esm/deferment/defermentManager.test.js +186 -0
  172. package/dist/esm/deferment/defermentManager.test.js.map +1 -0
  173. package/dist/esm/deferment/deferredBase.d.ts +12 -0
  174. package/dist/esm/deferment/deferredBase.d.ts.map +1 -0
  175. package/dist/esm/deferment/deferredBase.js +23 -0
  176. package/dist/esm/deferment/deferredBase.js.map +1 -0
  177. package/dist/esm/index.d.ts +3 -3
  178. package/dist/esm/index.d.ts.map +1 -1
  179. package/dist/esm/index.js +3 -3
  180. package/dist/esm/index.js.map +1 -1
  181. package/dist/esm/{helpers → queues}/aggregateQueue.d.ts +2 -1
  182. package/dist/esm/queues/aggregateQueue.d.ts.map +1 -0
  183. package/dist/esm/{helpers → queues}/aggregateQueue.js +4 -0
  184. package/dist/esm/queues/aggregateQueue.js.map +1 -0
  185. package/dist/{commonjs/helpers → esm/queues}/asyncGeneratorQueue.d.ts +1 -1
  186. package/dist/esm/queues/asyncGeneratorQueue.d.ts.map +1 -0
  187. package/dist/esm/{helpers → queues}/asyncGeneratorQueue.js +2 -1
  188. package/dist/esm/queues/asyncGeneratorQueue.js.map +1 -0
  189. package/dist/{commonjs/helpers → esm/queues}/batchedPool.d.ts +2 -1
  190. package/dist/esm/queues/batchedPool.d.ts.map +1 -0
  191. package/dist/esm/queues/batchedPool.js.map +1 -0
  192. package/dist/{commonjs/helpers → esm/queues}/batchingQueue.d.ts +4 -1
  193. package/dist/esm/queues/batchingQueue.d.ts.map +1 -0
  194. package/dist/esm/queues/batchingQueue.dispose.test.d.ts +2 -0
  195. package/dist/esm/queues/batchingQueue.dispose.test.d.ts.map +1 -0
  196. package/dist/esm/queues/batchingQueue.dispose.test.js +59 -0
  197. package/dist/esm/queues/batchingQueue.dispose.test.js.map +1 -0
  198. package/dist/esm/queues/batchingQueue.js +117 -0
  199. package/dist/esm/queues/batchingQueue.js.map +1 -0
  200. package/dist/esm/queues/batchingQueue.test.d.ts +2 -0
  201. package/dist/esm/queues/batchingQueue.test.d.ts.map +1 -0
  202. package/dist/esm/queues/batchingQueue.test.js +133 -0
  203. package/dist/esm/queues/batchingQueue.test.js.map +1 -0
  204. package/dist/{commonjs/helpers → esm/queues}/bufferQueue.d.ts +1 -0
  205. package/dist/esm/queues/bufferQueue.d.ts.map +1 -0
  206. package/dist/esm/{helpers → queues}/bufferQueue.js +3 -0
  207. package/dist/esm/queues/bufferQueue.js.map +1 -0
  208. package/dist/esm/{helpers → queues}/keyedQueue.d.ts +1 -0
  209. package/dist/esm/queues/keyedQueue.d.ts.map +1 -0
  210. package/dist/esm/{helpers → queues}/keyedQueue.js +11 -0
  211. package/dist/esm/queues/keyedQueue.js.map +1 -0
  212. package/dist/esm/queues/queue.d.ts +5 -0
  213. package/dist/esm/queues/queue.d.ts.map +1 -0
  214. package/dist/esm/{helpers → queues}/queue.js.map +1 -1
  215. package/dist/esm/types/functions.d.ts +21 -0
  216. package/dist/esm/types/functions.d.ts.map +1 -0
  217. package/dist/esm/types/functions.js +83 -0
  218. package/dist/esm/types/functions.js.map +1 -0
  219. package/dist/esm/types/types.d.ts +1 -7
  220. package/dist/esm/types/types.d.ts.map +1 -1
  221. package/dist/esm/types/types.js +1 -32
  222. package/dist/esm/types/types.js.map +1 -1
  223. package/package.json +2 -3
  224. package/readme.md +64 -16
  225. package/src/{operations → core}/interfaces.ts +2 -3
  226. package/src/{operations → core}/objectLoader2.spec.ts +22 -9
  227. package/src/core/objectLoader2.ts +162 -0
  228. package/src/core/objectLoader2Factory.ts +87 -0
  229. package/src/{operations → core}/options.ts +2 -1
  230. package/src/core/stages/ItemStore.ts +196 -0
  231. package/src/core/stages/__snapshots__/indexedDatabase.spec.ts.snap +18 -0
  232. package/src/{operations/downloaders → core/stages}/__snapshots__/serverDownloader.spec.ts.snap +25 -0
  233. package/src/{helpers → core/stages}/cacheReader.spec.ts +12 -7
  234. package/src/core/stages/cacheReader.ts +88 -0
  235. package/src/core/stages/cacheWriter.spec.ts +213 -0
  236. package/src/core/stages/cacheWriter.ts +64 -0
  237. package/src/core/stages/indexedDatabase.spec.ts +37 -0
  238. package/src/core/stages/indexedDatabase.ts +49 -0
  239. package/src/core/stages/memory/__snapshots__/memoryDownloader.spec.ts.snap +12 -0
  240. package/src/core/stages/memory/memoryDatabase.spec.ts +48 -0
  241. package/src/{operations/databases → core/stages/memory}/memoryDatabase.ts +7 -12
  242. package/src/core/stages/memory/memoryDownloader.spec.ts +49 -0
  243. package/src/{operations/downloaders → core/stages/memory}/memoryDownloader.ts +4 -4
  244. package/src/{operations/downloaders → core/stages}/serverDownloader.spec.ts +102 -11
  245. package/src/{operations/downloaders → core/stages}/serverDownloader.ts +88 -31
  246. package/src/{operations → core}/traverser.ts +2 -1
  247. package/src/deferment/MemoryCache.test.ts +187 -0
  248. package/src/deferment/MemoryCache.ts +189 -0
  249. package/src/deferment/defermentManager.test.ts +220 -0
  250. package/src/deferment/defermentManager.ts +59 -0
  251. package/src/deferment/deferredBase.ts +29 -0
  252. package/src/index.ts +3 -3
  253. package/src/{helpers → queues}/aggregateQueue.ts +5 -1
  254. package/src/{helpers → queues}/asyncGeneratorQueue.ts +2 -1
  255. package/src/{helpers → queues}/batchedPool.ts +3 -1
  256. package/src/queues/batchingQueue.dispose.test.ts +74 -0
  257. package/src/queues/batchingQueue.test.ts +149 -0
  258. package/src/queues/batchingQueue.ts +138 -0
  259. package/src/{helpers → queues}/bufferQueue.ts +3 -0
  260. package/src/{helpers → queues}/keyedQueue.ts +12 -0
  261. package/src/{helpers → queues}/queue.ts +1 -0
  262. package/src/test/e2e.spec.ts +6 -4
  263. package/src/types/functions.spec.ts +155 -0
  264. package/src/types/functions.ts +118 -0
  265. package/src/types/types.ts +1 -51
  266. package/dist/commonjs/helpers/aggregateQueue.d.ts.map +0 -1
  267. package/dist/commonjs/helpers/aggregateQueue.js.map +0 -1
  268. package/dist/commonjs/helpers/asyncGeneratorQueue.d.ts.map +0 -1
  269. package/dist/commonjs/helpers/asyncGeneratorQueue.js.map +0 -1
  270. package/dist/commonjs/helpers/batchedPool.d.ts.map +0 -1
  271. package/dist/commonjs/helpers/batchedPool.js.map +0 -1
  272. package/dist/commonjs/helpers/batchingQueue.d.ts.map +0 -1
  273. package/dist/commonjs/helpers/batchingQueue.js +0 -77
  274. package/dist/commonjs/helpers/batchingQueue.js.map +0 -1
  275. package/dist/commonjs/helpers/bufferQueue.d.ts.map +0 -1
  276. package/dist/commonjs/helpers/bufferQueue.js.map +0 -1
  277. package/dist/commonjs/helpers/cachePump.d.ts +0 -21
  278. package/dist/commonjs/helpers/cachePump.d.ts.map +0 -1
  279. package/dist/commonjs/helpers/cachePump.js +0 -80
  280. package/dist/commonjs/helpers/cachePump.js.map +0 -1
  281. package/dist/commonjs/helpers/cacheReader.d.ts +0 -14
  282. package/dist/commonjs/helpers/cacheReader.d.ts.map +0 -1
  283. package/dist/commonjs/helpers/cacheReader.js +0 -58
  284. package/dist/commonjs/helpers/cacheReader.js.map +0 -1
  285. package/dist/commonjs/helpers/defermentManager.d.ts +0 -26
  286. package/dist/commonjs/helpers/defermentManager.d.ts.map +0 -1
  287. package/dist/commonjs/helpers/defermentManager.js +0 -131
  288. package/dist/commonjs/helpers/defermentManager.js.map +0 -1
  289. package/dist/commonjs/helpers/deferredBase.d.ts +0 -19
  290. package/dist/commonjs/helpers/deferredBase.d.ts.map +0 -1
  291. package/dist/commonjs/helpers/deferredBase.js +0 -51
  292. package/dist/commonjs/helpers/deferredBase.js.map +0 -1
  293. package/dist/commonjs/helpers/keyedQueue.d.ts.map +0 -1
  294. package/dist/commonjs/helpers/keyedQueue.js.map +0 -1
  295. package/dist/commonjs/helpers/memoryPump.d.ts +0 -15
  296. package/dist/commonjs/helpers/memoryPump.d.ts.map +0 -1
  297. package/dist/commonjs/helpers/memoryPump.js +0 -34
  298. package/dist/commonjs/helpers/memoryPump.js.map +0 -1
  299. package/dist/commonjs/helpers/pump.d.ts +0 -8
  300. package/dist/commonjs/helpers/pump.d.ts.map +0 -1
  301. package/dist/commonjs/helpers/pump.js +0 -3
  302. package/dist/commonjs/helpers/pump.js.map +0 -1
  303. package/dist/commonjs/helpers/queue.d.ts +0 -4
  304. package/dist/commonjs/helpers/queue.d.ts.map +0 -1
  305. package/dist/commonjs/operations/databases/indexedDatabase.d.ts.map +0 -1
  306. package/dist/commonjs/operations/databases/indexedDatabase.js +0 -117
  307. package/dist/commonjs/operations/databases/indexedDatabase.js.map +0 -1
  308. package/dist/commonjs/operations/databases/memoryDatabase.d.ts +0 -16
  309. package/dist/commonjs/operations/databases/memoryDatabase.d.ts.map +0 -1
  310. package/dist/commonjs/operations/databases/memoryDatabase.js.map +0 -1
  311. package/dist/commonjs/operations/downloaders/memoryDownloader.d.ts.map +0 -1
  312. package/dist/commonjs/operations/downloaders/memoryDownloader.js.map +0 -1
  313. package/dist/commonjs/operations/downloaders/serverDownloader.d.ts.map +0 -1
  314. package/dist/commonjs/operations/downloaders/serverDownloader.js.map +0 -1
  315. package/dist/commonjs/operations/interfaces.d.ts.map +0 -1
  316. package/dist/commonjs/operations/interfaces.js.map +0 -1
  317. package/dist/commonjs/operations/objectLoader2.d.ts.map +0 -1
  318. package/dist/commonjs/operations/objectLoader2.js +0 -95
  319. package/dist/commonjs/operations/objectLoader2.js.map +0 -1
  320. package/dist/commonjs/operations/objectLoader2Factory.d.ts +0 -21
  321. package/dist/commonjs/operations/objectLoader2Factory.d.ts.map +0 -1
  322. package/dist/commonjs/operations/objectLoader2Factory.js +0 -50
  323. package/dist/commonjs/operations/objectLoader2Factory.js.map +0 -1
  324. package/dist/commonjs/operations/options.d.ts.map +0 -1
  325. package/dist/commonjs/operations/traverser.d.ts.map +0 -1
  326. package/dist/commonjs/operations/traverser.js.map +0 -1
  327. package/dist/esm/helpers/aggregateQueue.d.ts.map +0 -1
  328. package/dist/esm/helpers/aggregateQueue.js.map +0 -1
  329. package/dist/esm/helpers/asyncGeneratorQueue.d.ts.map +0 -1
  330. package/dist/esm/helpers/asyncGeneratorQueue.js.map +0 -1
  331. package/dist/esm/helpers/batchedPool.d.ts.map +0 -1
  332. package/dist/esm/helpers/batchedPool.js.map +0 -1
  333. package/dist/esm/helpers/batchingQueue.d.ts.map +0 -1
  334. package/dist/esm/helpers/batchingQueue.js +0 -71
  335. package/dist/esm/helpers/batchingQueue.js.map +0 -1
  336. package/dist/esm/helpers/bufferQueue.d.ts.map +0 -1
  337. package/dist/esm/helpers/bufferQueue.js.map +0 -1
  338. package/dist/esm/helpers/cachePump.d.ts +0 -21
  339. package/dist/esm/helpers/cachePump.d.ts.map +0 -1
  340. package/dist/esm/helpers/cachePump.js +0 -73
  341. package/dist/esm/helpers/cachePump.js.map +0 -1
  342. package/dist/esm/helpers/cacheReader.d.ts +0 -14
  343. package/dist/esm/helpers/cacheReader.d.ts.map +0 -1
  344. package/dist/esm/helpers/cacheReader.js +0 -51
  345. package/dist/esm/helpers/cacheReader.js.map +0 -1
  346. package/dist/esm/helpers/defermentManager.d.ts +0 -26
  347. package/dist/esm/helpers/defermentManager.d.ts.map +0 -1
  348. package/dist/esm/helpers/defermentManager.js +0 -127
  349. package/dist/esm/helpers/defermentManager.js.map +0 -1
  350. package/dist/esm/helpers/deferredBase.d.ts +0 -19
  351. package/dist/esm/helpers/deferredBase.d.ts.map +0 -1
  352. package/dist/esm/helpers/deferredBase.js +0 -47
  353. package/dist/esm/helpers/deferredBase.js.map +0 -1
  354. package/dist/esm/helpers/keyedQueue.d.ts.map +0 -1
  355. package/dist/esm/helpers/keyedQueue.js.map +0 -1
  356. package/dist/esm/helpers/memoryPump.d.ts +0 -15
  357. package/dist/esm/helpers/memoryPump.d.ts.map +0 -1
  358. package/dist/esm/helpers/memoryPump.js +0 -30
  359. package/dist/esm/helpers/memoryPump.js.map +0 -1
  360. package/dist/esm/helpers/pump.d.ts +0 -8
  361. package/dist/esm/helpers/pump.d.ts.map +0 -1
  362. package/dist/esm/helpers/pump.js +0 -2
  363. package/dist/esm/helpers/pump.js.map +0 -1
  364. package/dist/esm/helpers/queue.d.ts +0 -4
  365. package/dist/esm/helpers/queue.d.ts.map +0 -1
  366. package/dist/esm/operations/databases/indexedDatabase.d.ts.map +0 -1
  367. package/dist/esm/operations/databases/indexedDatabase.js +0 -114
  368. package/dist/esm/operations/databases/indexedDatabase.js.map +0 -1
  369. package/dist/esm/operations/databases/memoryDatabase.d.ts +0 -16
  370. package/dist/esm/operations/databases/memoryDatabase.d.ts.map +0 -1
  371. package/dist/esm/operations/databases/memoryDatabase.js.map +0 -1
  372. package/dist/esm/operations/downloaders/memoryDownloader.d.ts.map +0 -1
  373. package/dist/esm/operations/downloaders/memoryDownloader.js.map +0 -1
  374. package/dist/esm/operations/downloaders/serverDownloader.d.ts.map +0 -1
  375. package/dist/esm/operations/downloaders/serverDownloader.js.map +0 -1
  376. package/dist/esm/operations/interfaces.d.ts.map +0 -1
  377. package/dist/esm/operations/interfaces.js.map +0 -1
  378. package/dist/esm/operations/objectLoader2.d.ts.map +0 -1
  379. package/dist/esm/operations/objectLoader2.js +0 -88
  380. package/dist/esm/operations/objectLoader2.js.map +0 -1
  381. package/dist/esm/operations/objectLoader2Factory.d.ts +0 -21
  382. package/dist/esm/operations/objectLoader2Factory.d.ts.map +0 -1
  383. package/dist/esm/operations/objectLoader2Factory.js +0 -43
  384. package/dist/esm/operations/objectLoader2Factory.js.map +0 -1
  385. package/dist/esm/operations/options.d.ts.map +0 -1
  386. package/dist/esm/operations/traverser.d.ts.map +0 -1
  387. package/dist/esm/operations/traverser.js.map +0 -1
  388. package/src/helpers/__snapshots__/cachePump.spec.ts.snap +0 -31
  389. package/src/helpers/__snapshots__/defermentManager.spec.ts.snap +0 -8
  390. package/src/helpers/batchingQueue.ts +0 -85
  391. package/src/helpers/cachePump.disposal.spec.ts +0 -49
  392. package/src/helpers/cachePump.spec.ts +0 -103
  393. package/src/helpers/cachePump.ts +0 -99
  394. package/src/helpers/cacheReader.ts +0 -64
  395. package/src/helpers/defermentManager.disposal.spec.ts +0 -28
  396. package/src/helpers/defermentManager.spec.ts +0 -37
  397. package/src/helpers/defermentManager.ts +0 -141
  398. package/src/helpers/deferredBase.ts +0 -55
  399. package/src/helpers/memoryPump.ts +0 -40
  400. package/src/helpers/pump.ts +0 -8
  401. package/src/operations/databases/__snapshots__/indexedDatabase.spec.ts.snap +0 -31
  402. package/src/operations/databases/indexedDatabase.spec.ts +0 -37
  403. package/src/operations/databases/indexedDatabase.ts +0 -150
  404. package/src/operations/objectLoader2.ts +0 -111
  405. package/src/operations/objectLoader2Factory.ts +0 -56
  406. package/dist/commonjs/{operations → core}/interfaces.js +0 -0
  407. package/dist/commonjs/{operations → core}/options.js +0 -0
  408. package/dist/commonjs/{operations → core}/traverser.d.ts +0 -0
  409. package/dist/commonjs/{helpers → queues}/batchedPool.js +0 -0
  410. package/dist/commonjs/{helpers → queues}/queue.js +0 -0
  411. package/dist/esm/{operations → core}/interfaces.js +0 -0
  412. package/dist/esm/{operations → core}/options.js +0 -0
  413. package/dist/esm/{operations → core}/traverser.d.ts +0 -0
  414. package/dist/esm/{helpers → queues}/batchedPool.js +0 -0
  415. package/dist/esm/{helpers → queues}/queue.js +0 -0
  416. package/src/{operations → core}/__snapshots__/objectLoader2.spec.ts.snap +0 -0
  417. package/src/{operations → core}/__snapshots__/traverser.spec.ts.snap +0 -0
  418. package/src/{helpers → core/stages}/__snapshots__/cacheReader.spec.ts.snap +0 -0
  419. package/src/{operations → core}/traverser.spec.ts +1 -1
@@ -3,14 +3,14 @@ import createFetchMock from 'vitest-fetch-mock'
3
3
  import { vi } from 'vitest'
4
4
  import { Item } from '../../types/types.js'
5
5
  import ServerDownloader from './serverDownloader.js'
6
- import { MemoryPump } from '../../helpers/memoryPump.js'
6
+ import AsyncGeneratorQueue from '../../queues/asyncGeneratorQueue.js'
7
7
 
8
8
  describe('downloader', () => {
9
9
  test('download batch of one', async () => {
10
10
  const fetchMocker = createFetchMock(vi)
11
11
  const i: Item = { baseId: 'id', base: { id: 'id', speckle_type: 'type' } }
12
12
  fetchMocker.mockResponseOnce('id\t' + JSON.stringify(i.base) + '\n')
13
- const pump = new MemoryPump()
13
+ const gathered = new AsyncGeneratorQueue<Item>()
14
14
  const downloader = new ServerDownloader({
15
15
  serverUrl: 'http://speckle.test',
16
16
  streamId: 'streamId',
@@ -18,12 +18,18 @@ describe('downloader', () => {
18
18
  token: 'token',
19
19
  fetch: fetchMocker
20
20
  })
21
- downloader.initializePool({ results: pump, total: 1, maxDownloadBatchWait: 200 })
21
+ downloader.initializePool({
22
+ results: gathered,
23
+ total: 1,
24
+ maxDownloadBatchWait: 200
25
+ })
22
26
  downloader.add('id')
23
- await downloader.disposeAsync()
24
27
  const r = []
25
- for await (const x of pump.gather([i.baseId])) {
28
+ for await (const x of gathered.consume()) {
26
29
  r.push(x)
30
+ if (r.length >= 1) {
31
+ break
32
+ }
27
33
  }
28
34
 
29
35
  expect(r).toMatchSnapshot()
@@ -38,7 +44,7 @@ describe('downloader', () => {
38
44
  'id1\t' + JSON.stringify(i1.base) + '\nid2\t' + JSON.stringify(i2.base) + '\n'
39
45
  )
40
46
 
41
- const pump = new MemoryPump()
47
+ const gathered = new AsyncGeneratorQueue<Item>()
42
48
  const downloader = new ServerDownloader({
43
49
  serverUrl: 'http://speckle.test',
44
50
  streamId: 'streamId',
@@ -47,13 +53,20 @@ describe('downloader', () => {
47
53
 
48
54
  fetch: fetchMocker
49
55
  })
50
- downloader.initializePool({ results: pump, total: 2, maxDownloadBatchWait: 200 })
56
+ downloader.initializePool({
57
+ results: gathered,
58
+ total: 2,
59
+ maxDownloadBatchWait: 200
60
+ })
51
61
  downloader.add('id1')
52
62
  downloader.add('id2')
53
63
  await downloader.disposeAsync()
54
64
  const r = []
55
- for await (const x of pump.gather([i1.baseId, i2.baseId])) {
65
+ for await (const x of gathered.consume()) {
56
66
  r.push(x)
67
+ if (r.length >= 2) {
68
+ break
69
+ }
57
70
  }
58
71
 
59
72
  expect(r).toMatchSnapshot()
@@ -75,7 +88,7 @@ describe('downloader', () => {
75
88
  '\n'
76
89
  )
77
90
 
78
- const pump = new MemoryPump()
91
+ const gathered = new AsyncGeneratorQueue<Item>()
79
92
  const downloader = new ServerDownloader({
80
93
  serverUrl: 'http://speckle.test',
81
94
  streamId: 'streamId',
@@ -84,20 +97,98 @@ describe('downloader', () => {
84
97
 
85
98
  fetch: fetchMocker
86
99
  })
87
- downloader.initializePool({ results: pump, total: 3, maxDownloadBatchWait: 200 })
100
+ downloader.initializePool({
101
+ results: gathered,
102
+ total: 3,
103
+ maxDownloadBatchWait: 200
104
+ })
88
105
  downloader.add('id1')
89
106
  downloader.add('id2')
90
107
  downloader.add('id3')
91
108
  await downloader.disposeAsync()
92
109
  const r = []
93
- for await (const x of pump.gather([i1.baseId, i2.baseId, i3.baseId])) {
110
+ for await (const x of gathered.consume()) {
94
111
  r.push(x)
112
+ if (r.length >= 3) {
113
+ break
114
+ }
95
115
  }
96
116
 
97
117
  expect(r).toMatchSnapshot()
98
118
  await downloader.disposeAsync()
99
119
  })
100
120
 
121
+ test('download batch of three with Objects.Other.RawEncoding', async () => {
122
+ const fetchMocker = createFetchMock(vi)
123
+ const i1: Item = { baseId: 'id1', base: { id: 'id1', speckle_type: 'type' } }
124
+ const i2: Item = {
125
+ baseId: 'id2',
126
+ base: { id: 'id2', speckle_type: 'Objects.Other.RawEncoding' }
127
+ }
128
+ const i3: Item = { baseId: 'id3', base: { id: 'id3', speckle_type: 'type' } }
129
+ fetchMocker.mockResponseOnce(
130
+ 'id1\t' +
131
+ JSON.stringify(i1.base) +
132
+ '\nid2\t' +
133
+ JSON.stringify(i2.base) +
134
+ '\nid3\t' +
135
+ JSON.stringify(i3.base) +
136
+ '\n'
137
+ )
138
+
139
+ const gathered = new AsyncGeneratorQueue<Item>()
140
+ const downloader = new ServerDownloader({
141
+ serverUrl: 'http://speckle.test',
142
+ streamId: 'streamId',
143
+ objectId: 'objectId',
144
+ token: 'token',
145
+
146
+ fetch: fetchMocker
147
+ })
148
+ downloader.initializePool({
149
+ results: gathered,
150
+ total: 3,
151
+ maxDownloadBatchWait: 200
152
+ })
153
+ downloader.add('id1')
154
+ downloader.add('id2')
155
+ downloader.add('id3')
156
+ await downloader.disposeAsync()
157
+ const r = []
158
+ for await (const x of gathered.consume()) {
159
+ r.push(x)
160
+ if (r.length >= 3) {
161
+ break
162
+ }
163
+ }
164
+
165
+ expect(r).toMatchSnapshot()
166
+ await downloader.disposeAsync()
167
+ })
168
+
169
+ test("download Objects.Other.RawEncoding doesn't exist", async () => {
170
+ const fetchMocker = createFetchMock(vi)
171
+ const i: Item = {
172
+ baseId: 'id',
173
+ base: {
174
+ id: 'id',
175
+ speckle_type: 'Objects.Other.RawEncoding',
176
+ __closure: { childIds: 1 }
177
+ }
178
+ }
179
+ fetchMocker.mockResponseOnce(JSON.stringify(i.base))
180
+ const downloader = new ServerDownloader({
181
+ serverUrl: 'http://speckle.test',
182
+ streamId: 'streamId',
183
+ objectId: i.baseId,
184
+ token: 'token',
185
+
186
+ fetch: fetchMocker
187
+ })
188
+ await expect(downloader.downloadSingle()).rejects.toThrow()
189
+ await downloader.disposeAsync()
190
+ })
191
+
101
192
  test('download single exists', async () => {
102
193
  const fetchMocker = createFetchMock(vi)
103
194
  const i: Item = {
@@ -1,7 +1,8 @@
1
- import BatchedPool from '../../helpers/batchedPool.js'
2
- import Queue from '../../helpers/queue.js'
1
+ import BatchedPool from '../../queues/batchedPool.js'
2
+ import Queue from '../../queues/queue.js'
3
3
  import { ObjectLoaderRuntimeError } from '../../types/errors.js'
4
- import { Fetcher, isBase, Item, take } from '../../types/types.js'
4
+ import { Fetcher, indexOf, isBase, take } from '../../types/functions.js'
5
+ import { Item } from '../../types/types.js'
5
6
  import { Downloader } from '../interfaces.js'
6
7
 
7
8
  export interface ServerDownloaderOptions {
@@ -13,6 +14,8 @@ export interface ServerDownloaderOptions {
13
14
  fetch?: Fetcher
14
15
  }
15
16
 
17
+ const MAX_SAFARI_DECODE_BYTES = 2 * 1024 * 1024 * 1024 - 1024 * 1024 // 2GB minus a margin
18
+
16
19
  export default class ServerDownloader implements Downloader {
17
20
  #requestUrlRootObj: string
18
21
  #requestUrlChildren: string
@@ -20,9 +23,14 @@ export default class ServerDownloader implements Downloader {
20
23
  #options: ServerDownloaderOptions
21
24
  #fetch: Fetcher
22
25
  #results?: Queue<Item>
26
+ #total?: number
23
27
 
24
28
  #downloadQueue?: BatchedPool<string>
25
- #decoder = new TextDecoder()
29
+ #decoder = new TextDecoder('utf-8', { fatal: true })
30
+ #decodedBytesCount = 0
31
+
32
+ #rawString: string = 'Objects.Other.RawEncoding'
33
+ #rawEncoding: Uint8Array
26
34
 
27
35
  constructor(options: ServerDownloaderOptions) {
28
36
  this.#options = options
@@ -46,6 +54,9 @@ export default class ServerDownloader implements Downloader {
46
54
  this.#requestUrlRootObj = `${this.#options.serverUrl}/objects/${
47
55
  this.#options.streamId
48
56
  }/${this.#options.objectId}/single`
57
+
58
+ const encoder = new TextEncoder()
59
+ this.#rawEncoding = encoder.encode(this.#rawString)
49
60
  }
50
61
 
51
62
  #getDownloadCountAndSizes(total: number): number[] {
@@ -53,7 +64,7 @@ export default class ServerDownloader implements Downloader {
53
64
  return [total]
54
65
  }
55
66
 
56
- return [10000, 30000, 10000, 1000]
67
+ return [10000, 25000, 10000, 1000]
57
68
  }
58
69
 
59
70
  initializePool(params: {
@@ -63,6 +74,7 @@ export default class ServerDownloader implements Downloader {
63
74
  }): void {
64
75
  const { results, total } = params
65
76
  this.#results = results
77
+ this.#total = total
66
78
  this.#downloadQueue = new BatchedPool<string>({
67
79
  concurrencyAndSizes: this.#getDownloadCountAndSizes(total),
68
80
  maxWaitTime: params.maxDownloadBatchWait,
@@ -86,22 +98,26 @@ export default class ServerDownloader implements Downloader {
86
98
  this.#getPool().add(id)
87
99
  }
88
100
 
89
- async disposeAsync(): Promise<void> {
90
- await this.#downloadQueue?.disposeAsync()
91
- }
101
+ /*
102
+ This is the most frequently reported and confirmed reason for this error in Safari. There's a known bug in WebKit (Safari's rendering engine) where TextDecoder can fail or throw a RangeError after decoding around 2GB of data. Chrome and other browsers handle much larger amounts of data without this specific limitation.
92
103
 
93
- #processJson(baseId: string, unparsedBase: string): Item {
94
- let base: unknown
95
- try {
96
- base = JSON.parse(unparsedBase)
97
- } catch (e: unknown) {
98
- throw new Error(`Error parsing object ${baseId}: ${(e as Error).message}`)
99
- }
100
- if (isBase(base)) {
101
- return { baseId, base }
102
- } else {
103
- throw new ObjectLoaderRuntimeError(`${baseId} is not a base`)
104
+ Why it happens: It seems to be an internal memory or indexing limitation within Safari's TextDecoder implementation. After a certain threshold of data has been processed by a TextDecoder instance, it starts throwing this error.
105
+
106
+ Chrome's behavior: Chrome generally handles larger data sizes without this specific RangeError. It might become slow or run out of general memory, but not typically with this specific error.
107
+ */
108
+ decodeChunk(chunkBuffer: Uint8Array): string {
109
+ if (this.#decodedBytesCount + chunkBuffer.byteLength > MAX_SAFARI_DECODE_BYTES) {
110
+ // Safari is approaching its limit, create a new decoder
111
+ this.#decoder = new TextDecoder('utf-8', { fatal: true })
112
+ this.#decodedBytesCount = 0 // Reset counter for the new decoder
104
113
  }
114
+ const decodedText = this.#decoder.decode(chunkBuffer)
115
+ this.#decodedBytesCount += chunkBuffer.byteLength
116
+ return decodedText
117
+ }
118
+
119
+ async disposeAsync(): Promise<void> {
120
+ await this.#downloadQueue?.disposeAsync()
105
121
  }
106
122
 
107
123
  async downloadBatch(params: {
@@ -130,7 +146,7 @@ export default class ServerDownloader implements Downloader {
130
146
  const { done, value } = await reader.read()
131
147
  if (done) break
132
148
 
133
- leftover = await this.processArray(leftover, value, keys, async () => {
149
+ leftover = await this.#processArray(leftover, value, keys, async () => {
134
150
  count++
135
151
  if (count % 1000 === 0) {
136
152
  await new Promise((resolve) => setTimeout(resolve, 100)) //allow other stuff to happen
@@ -142,16 +158,20 @@ export default class ServerDownloader implements Downloader {
142
158
  'Items requested were not downloaded: ' + take(keys.values(), 10).join(',')
143
159
  )
144
160
  }
161
+ count += keys.size // count the leftovers
162
+ if (count >= this.#total!) {
163
+ await this.#results?.disposeAsync() // mark the queue as done
164
+ }
145
165
  }
146
166
 
147
- async processArray(
167
+ async #processArray(
148
168
  leftover: Uint8Array,
149
169
  value: Uint8Array,
150
170
  keys: Set<string>,
151
171
  callback: () => Promise<void>
152
172
  ): Promise<Uint8Array> {
153
173
  //this concat will allocate a new array
154
- const combined = this.concatUint8Arrays(leftover, value)
174
+ const combined = this.#concatUint8Arrays(leftover, value)
155
175
  let start = 0
156
176
 
157
177
  //subarray doesn't allocate
@@ -159,34 +179,65 @@ export default class ServerDownloader implements Downloader {
159
179
  if (combined[i] === 0x0a) {
160
180
  const line = combined.subarray(start, i) // line without \n
161
181
  //strings are allocated here
162
- const item = this.processLine(line)
163
- this.#results?.add(item)
182
+ const item = this.#processLine(line)
164
183
  start = i + 1
165
184
  await callback()
166
185
  keys.delete(item.baseId)
186
+ this.#results?.add(item)
167
187
  }
168
188
  }
169
189
  return combined.subarray(start) // carry over remainder
170
190
  }
171
191
 
172
- processLine(line: Uint8Array): Item {
192
+ #processLine(line: Uint8Array): Item {
173
193
  for (let i = 0; i < line.length; i++) {
174
194
  if (line[i] === 0x09) {
175
195
  //this is a tab
176
- const baseId = this.#decoder.decode(line.subarray(0, i))
177
- const json = line.subarray(i + 1)
178
- const base = this.#decoder.decode(json)
196
+ const baseId = this.decodeChunk(line.subarray(0, i))
197
+ const jsonBytes = line.subarray(i + 1)
198
+
199
+ if (!this.#isValidBytes(jsonBytes)) {
200
+ return { baseId, base: undefined }
201
+ }
202
+ const base = this.decodeChunk(jsonBytes)
179
203
  const item = this.#processJson(baseId, base)
180
- item.size = json.length
204
+ item.size = jsonBytes.length
181
205
  return item
182
206
  }
183
207
  }
184
208
  throw new ObjectLoaderRuntimeError(
185
- 'Invalid line format: ' + this.#decoder.decode(line)
209
+ 'Invalid line format in response: ' + this.decodeChunk(line)
186
210
  )
187
211
  }
188
212
 
189
- concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array {
213
+ #processJson(baseId: string, unparsedBase: string): Item {
214
+ let base: unknown
215
+ try {
216
+ base = JSON.parse(unparsedBase)
217
+ } catch (e: unknown) {
218
+ throw new Error(`Error parsing object ${baseId}: ${(e as Error).message}`)
219
+ }
220
+ if (isBase(base)) {
221
+ return { baseId, base }
222
+ } else {
223
+ throw new ObjectLoaderRuntimeError(`${baseId} is not a base`)
224
+ }
225
+ }
226
+ #isValidString(json: string): boolean {
227
+ if (!json.includes(this.#rawString)) {
228
+ return true
229
+ }
230
+ return false
231
+ }
232
+
233
+ #isValidBytes(json: Uint8Array): boolean {
234
+ if (indexOf(json, this.#rawEncoding) === -1) {
235
+ return true
236
+ }
237
+ return false
238
+ }
239
+
240
+ #concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array {
190
241
  const c = new Uint8Array(a.length + b.length)
191
242
  c.set(a, 0)
192
243
  c.set(b, a.length)
@@ -199,7 +250,13 @@ export default class ServerDownloader implements Downloader {
199
250
  })
200
251
  this.#validateResponse(response)
201
252
  const responseText = await response.text()
253
+ if (!this.#isValidString(responseText)) {
254
+ throw new ObjectLoaderRuntimeError('Invalid base object')
255
+ }
202
256
  const item = this.#processJson(this.#options.objectId, responseText)
257
+ if (!item.base) {
258
+ throw new ObjectLoaderRuntimeError('Invalid base object')
259
+ }
203
260
  item.size = 0
204
261
  return item
205
262
  }
@@ -1,4 +1,5 @@
1
- import { Base, DataChunk, isBase, isReference, isScalar } from '../types/types.js'
1
+ import { isScalar, isBase, isReference } from '../types/functions.js'
2
+ import { Base, DataChunk } from '../types/types.js'
2
3
  import { ObjectLoader2 } from './objectLoader2.js'
3
4
 
4
5
  export type ProgressStage = 'download' | 'construction'
@@ -0,0 +1,187 @@
1
+ import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { MemoryCache, MemoryCacheItem, MemoryCacheOptions } from './MemoryCache.js'
3
+ import { Item, Base } from '../types/types.js'
4
+ import { CustomLogger } from '../types/functions.js'
5
+
6
+ const logger: CustomLogger = () => {
7
+ // console.log(message, ...optionalParams)
8
+ }
9
+
10
+ const defaultOptions: MemoryCacheOptions = {
11
+ maxSizeInMb: 10,
12
+ ttlms: 1000
13
+ }
14
+
15
+ const createItem = (id: string, size: number, referencedIds: string[] = []): Item => {
16
+ const base: Base & { data?: unknown } = {
17
+ id,
18
+ // eslint-disable-next-line camelcase
19
+ speckle_type: 'Base'
20
+ }
21
+
22
+ if (referencedIds.length > 0) {
23
+ base.data = referencedIds.map((referencedId) => ({
24
+ // eslint-disable-next-line camelcase
25
+ speckle_type: 'reference',
26
+ referencedId
27
+ }))
28
+ }
29
+
30
+ return {
31
+ baseId: id,
32
+ base,
33
+ size
34
+ }
35
+ }
36
+
37
+ describe('MemoryCacheItem', () => {
38
+ it('should correctly determine if it is expired', () => {
39
+ const item = createItem('1', 100)
40
+ const now = Date.now()
41
+ const cacheItem = new MemoryCacheItem(item, now + 1000)
42
+ expect(cacheItem.isExpired(now + 500)).toBe(false)
43
+ expect(cacheItem.isExpired(now + 1500)).toBe(true)
44
+ })
45
+
46
+ it('should update its access time', () => {
47
+ const item = createItem('1', 100)
48
+ const now = Date.now()
49
+ const cacheItem = new MemoryCacheItem(item, now + 1000)
50
+ cacheItem.setAccess(now + 500, 1000)
51
+ expect(cacheItem.isExpired(now + 1000)).toBe(false)
52
+ expect(cacheItem.isExpired(now + 1600)).toBe(true)
53
+ })
54
+
55
+ it('should return the correct item', () => {
56
+ const item = createItem('1', 100)
57
+ const cacheItem = new MemoryCacheItem(item, Date.now() + 1000)
58
+ expect(cacheItem.getItem()).toEqual(item)
59
+ })
60
+
61
+ it('should be done if expired', () => {
62
+ const item = createItem('1', 100)
63
+ const now = Date.now()
64
+ const cacheItem = new MemoryCacheItem(item, now + 1000)
65
+ expect(cacheItem.done(now + 1500)).toBe(true)
66
+ expect(cacheItem.done(now + 500)).toBe(false)
67
+ })
68
+ })
69
+
70
+ describe('MemoryCache', () => {
71
+ beforeEach(() => {
72
+ vi.useFakeTimers()
73
+ })
74
+
75
+ afterEach(() => {
76
+ vi.useRealTimers()
77
+ })
78
+
79
+ it('should add and get an item', () => {
80
+ const cache = new MemoryCache(defaultOptions, logger)
81
+ const item = createItem('1', 100)
82
+ const requestItem = vi.fn()
83
+
84
+ cache.add(item, requestItem)
85
+ const retrieved = cache.get('1')
86
+
87
+ expect(retrieved).toEqual(item)
88
+ expect(requestItem).not.toHaveBeenCalled()
89
+ })
90
+
91
+ it('should update expiry on get', () => {
92
+ const cache = new MemoryCache({ ...defaultOptions, ttlms: 100 }, logger)
93
+ const item = createItem('1', 100)
94
+ cache.add(item, vi.fn())
95
+
96
+ vi.advanceTimersByTime(50)
97
+ const retrieved = cache.get('1')
98
+ expect(retrieved).toBeDefined()
99
+
100
+ vi.advanceTimersByTime(80)
101
+ const retrievedAgain = cache.get('1')
102
+ expect(retrievedAgain).toBeDefined()
103
+ })
104
+
105
+ it('should return undefined for non-existent item', () => {
106
+ const cache = new MemoryCache(defaultOptions, logger)
107
+ expect(cache.get('non-existent')).toBeUndefined()
108
+ })
109
+
110
+ it('should scan for references and request missing ones', () => {
111
+ const cache = new MemoryCache(defaultOptions, logger)
112
+ const requestItem = vi.fn()
113
+ const item = createItem('1', 100, ['2', '3'])
114
+
115
+ cache.add(createItem('3', 50), vi.fn()) // pre-cache one of the references
116
+ cache.scanForReferences(item.base, requestItem)
117
+
118
+ expect(requestItem).toHaveBeenCalledTimes(1)
119
+ expect(requestItem).toHaveBeenCalledWith('2')
120
+ expect(requestItem).not.toHaveBeenCalledWith('3')
121
+ })
122
+
123
+ it('should clean up expired items when size exceeds max', () => {
124
+ const options = { maxSizeInMb: 0, ttlms: 100 } // 100 bytes
125
+ const cache = new MemoryCache(options, logger)
126
+ const requestItem = vi.fn()
127
+
128
+ const item1 = createItem('1', 60)
129
+ const item2 = createItem('2', 60)
130
+
131
+ const now = 1
132
+ cache.add(item1, requestItem, now - 200)
133
+ cache.cleanCache(now)
134
+ cache.add(item2, requestItem, now + 100)
135
+
136
+ expect(cache.get('1')).toBeUndefined()
137
+ expect(cache.get('2')).toBeDefined()
138
+ })
139
+
140
+ it('should not clean up expired items if they have references', () => {
141
+ const options = { maxSizeInMb: 0.0001, ttlms: 100 } // 100 bytes
142
+ const cache = new MemoryCache(options, logger)
143
+ const requestItem = vi.fn()
144
+
145
+ const item1 = createItem('1', 60)
146
+ const item2 = createItem('2', 60, ['1'])
147
+
148
+ cache.add(item1, requestItem)
149
+ vi.advanceTimersByTime(110) // item1 expires
150
+ cache.add(item2, requestItem) // item2 adds a reference to item1
151
+
152
+ vi.advanceTimersByTime(100)
153
+
154
+ expect(cache.get('1')).toBeDefined()
155
+ expect(cache.get('2')).toBeDefined()
156
+ })
157
+
158
+ it('compareMaybeBasesByReferences should sort correctly', () => {
159
+ const cache = new MemoryCache(defaultOptions, logger)
160
+ const requestItem = vi.fn()
161
+
162
+ const item1 = createItem('1', 10)
163
+ const item2 = createItem('2', 10)
164
+ const item3 = createItem('3', 10, ['1', '2'])
165
+ const item4 = createItem('4', 10, ['2'])
166
+
167
+ cache.add(item1, requestItem)
168
+ cache.add(item2, requestItem)
169
+ cache.add(item3, requestItem)
170
+ cache.add(item4, requestItem)
171
+
172
+ expect(cache.compareMaybeBasesByReferences('1', '2')).toBe(-1)
173
+ expect(cache.compareMaybeBasesByReferences('2', '1')).toBe(1)
174
+ expect(cache.compareMaybeBasesByReferences('1', '1')).toBe(0)
175
+ expect(cache.compareMaybeBasesByReferences('1', '5')).toBe(1)
176
+ expect(cache.compareMaybeBasesByReferences('5', '1')).toBe(-1)
177
+ expect(cache.compareMaybeBasesByReferences('5', '6')).toBe(0)
178
+ })
179
+
180
+ it('should throw when used after dispose', () => {
181
+ const cache = new MemoryCache(defaultOptions, logger)
182
+ cache.dispose()
183
+ const item = createItem('1', 100)
184
+ expect(() => cache.add(item, vi.fn())).toThrow('MemoryCache is disposed')
185
+ expect(() => cache.get('1')).toThrow('MemoryCache is disposed')
186
+ })
187
+ })