@synchronized-console/objectloader2 2.25.7 → 2.31.14

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 (423) hide show
  1. package/dist/commonjs/{operations → core}/interfaces.d.ts +5 -7
  2. package/dist/commonjs/core/interfaces.d.ts.map +1 -0
  3. package/dist/commonjs/core/interfaces.js.map +1 -0
  4. package/dist/commonjs/{operations → core}/objectLoader2.d.ts +1 -1
  5. package/dist/commonjs/core/objectLoader2.d.ts.map +1 -0
  6. package/dist/commonjs/core/objectLoader2.js +120 -0
  7. package/dist/commonjs/core/objectLoader2.js.map +1 -0
  8. package/dist/{esm/operations → commonjs/core}/objectLoader2Factory.d.ts +10 -2
  9. package/dist/commonjs/core/objectLoader2Factory.d.ts.map +1 -0
  10. package/dist/commonjs/core/objectLoader2Factory.js +86 -0
  11. package/dist/commonjs/core/objectLoader2Factory.js.map +1 -0
  12. package/dist/commonjs/core/objectLoader2Factory.test.d.ts +2 -0
  13. package/dist/commonjs/core/objectLoader2Factory.test.d.ts.map +1 -0
  14. package/dist/commonjs/core/objectLoader2Factory.test.js +106 -0
  15. package/dist/commonjs/core/objectLoader2Factory.test.js.map +1 -0
  16. package/dist/{esm/operations → commonjs/core}/options.d.ts +4 -1
  17. package/dist/commonjs/core/options.d.ts.map +1 -0
  18. package/dist/commonjs/{operations → core}/options.js.map +1 -1
  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/core/stages/indexedDatabase.d.ts +34 -0
  28. package/dist/commonjs/core/stages/indexedDatabase.d.ts.map +1 -0
  29. package/dist/commonjs/core/stages/indexedDatabase.js +150 -0
  30. package/dist/commonjs/core/stages/indexedDatabase.js.map +1 -0
  31. package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts +11 -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 +6 -3
  34. package/dist/commonjs/core/stages/memory/memoryDatabase.js.map +1 -0
  35. package/dist/commonjs/{operations/downloaders → core/stages/memory}/memoryDownloader.d.ts +4 -4
  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 +8 -6
  40. package/dist/commonjs/core/stages/serverDownloader.d.ts.map +1 -0
  41. package/dist/commonjs/{operations/downloaders → core/stages}/serverDownloader.js +99 -50
  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 +32 -0
  55. package/dist/commonjs/deferment/defermentManager.d.ts.map +1 -0
  56. package/dist/commonjs/deferment/defermentManager.js +85 -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 +193 -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 +4 -2
  67. package/dist/commonjs/index.d.ts.map +1 -1
  68. package/dist/commonjs/index.js +6 -3
  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/commonjs/{helpers → queues}/batchingQueue.d.ts +4 -1
  79. package/dist/commonjs/queues/batchingQueue.d.ts.map +1 -0
  80. package/dist/commonjs/queues/batchingQueue.dispose.test.d.ts +2 -0
  81. package/dist/commonjs/queues/batchingQueue.dispose.test.d.ts.map +1 -0
  82. package/dist/commonjs/queues/batchingQueue.dispose.test.js +62 -0
  83. package/dist/commonjs/queues/batchingQueue.dispose.test.js.map +1 -0
  84. package/dist/commonjs/queues/batchingQueue.js +128 -0
  85. package/dist/commonjs/queues/batchingQueue.js.map +1 -0
  86. package/dist/commonjs/queues/batchingQueue.test.d.ts +2 -0
  87. package/dist/commonjs/queues/batchingQueue.test.d.ts.map +1 -0
  88. package/dist/commonjs/queues/batchingQueue.test.js +236 -0
  89. package/dist/commonjs/queues/batchingQueue.test.js.map +1 -0
  90. package/dist/{esm/helpers → commonjs/queues}/bufferQueue.d.ts +1 -0
  91. package/dist/commonjs/queues/bufferQueue.d.ts.map +1 -0
  92. package/dist/commonjs/{helpers → queues}/bufferQueue.js +3 -0
  93. package/dist/commonjs/queues/bufferQueue.js.map +1 -0
  94. package/dist/commonjs/{helpers → queues}/keyedQueue.d.ts +1 -0
  95. package/dist/commonjs/queues/keyedQueue.d.ts.map +1 -0
  96. package/dist/commonjs/{helpers → queues}/keyedQueue.js +11 -0
  97. package/dist/commonjs/queues/keyedQueue.js.map +1 -0
  98. package/dist/commonjs/queues/keyedQueue.test.d.ts +2 -0
  99. package/dist/commonjs/queues/keyedQueue.test.d.ts.map +1 -0
  100. package/dist/commonjs/queues/keyedQueue.test.js +118 -0
  101. package/dist/commonjs/queues/keyedQueue.test.js.map +1 -0
  102. package/dist/commonjs/queues/queue.d.ts +5 -0
  103. package/dist/commonjs/queues/queue.d.ts.map +1 -0
  104. package/dist/commonjs/{helpers → queues}/queue.js.map +1 -1
  105. package/dist/commonjs/types/functions.d.ts +21 -0
  106. package/dist/commonjs/types/functions.d.ts.map +1 -0
  107. package/dist/commonjs/types/functions.js +92 -0
  108. package/dist/commonjs/types/functions.js.map +1 -0
  109. package/dist/commonjs/types/types.d.ts +6 -7
  110. package/dist/commonjs/types/types.d.ts.map +1 -1
  111. package/dist/commonjs/types/types.js +0 -36
  112. package/dist/commonjs/types/types.js.map +1 -1
  113. package/dist/esm/{operations → core}/interfaces.d.ts +5 -7
  114. package/dist/esm/core/interfaces.d.ts.map +1 -0
  115. package/dist/esm/core/interfaces.js.map +1 -0
  116. package/dist/esm/{operations → core}/objectLoader2.d.ts +1 -1
  117. package/dist/esm/core/objectLoader2.d.ts.map +1 -0
  118. package/dist/esm/core/objectLoader2.js +113 -0
  119. package/dist/esm/core/objectLoader2.js.map +1 -0
  120. package/dist/{commonjs/operations → esm/core}/objectLoader2Factory.d.ts +10 -2
  121. package/dist/esm/core/objectLoader2Factory.d.ts.map +1 -0
  122. package/dist/esm/core/objectLoader2Factory.js +79 -0
  123. package/dist/esm/core/objectLoader2Factory.js.map +1 -0
  124. package/dist/esm/core/objectLoader2Factory.test.d.ts +2 -0
  125. package/dist/esm/core/objectLoader2Factory.test.d.ts.map +1 -0
  126. package/dist/esm/core/objectLoader2Factory.test.js +104 -0
  127. package/dist/esm/core/objectLoader2Factory.test.js.map +1 -0
  128. package/dist/{commonjs/operations → esm/core}/options.d.ts +4 -1
  129. package/dist/esm/core/options.d.ts.map +1 -0
  130. package/dist/esm/{operations → core}/options.js.map +1 -1
  131. package/dist/esm/core/stages/cacheReader.d.ts +18 -0
  132. package/dist/esm/core/stages/cacheReader.d.ts.map +1 -0
  133. package/dist/esm/core/stages/cacheReader.js +65 -0
  134. package/dist/esm/core/stages/cacheReader.js.map +1 -0
  135. package/dist/esm/core/stages/cacheWriter.d.ts +15 -0
  136. package/dist/esm/core/stages/cacheWriter.d.ts.map +1 -0
  137. package/dist/esm/core/stages/cacheWriter.js +43 -0
  138. package/dist/esm/core/stages/cacheWriter.js.map +1 -0
  139. package/dist/esm/core/stages/indexedDatabase.d.ts +34 -0
  140. package/dist/esm/core/stages/indexedDatabase.d.ts.map +1 -0
  141. package/dist/esm/core/stages/indexedDatabase.js +146 -0
  142. package/dist/esm/core/stages/indexedDatabase.js.map +1 -0
  143. package/dist/esm/core/stages/memory/memoryDatabase.d.ts +11 -0
  144. package/dist/esm/core/stages/memory/memoryDatabase.d.ts.map +1 -0
  145. package/dist/esm/{operations/databases → core/stages/memory}/memoryDatabase.js +6 -3
  146. package/dist/esm/core/stages/memory/memoryDatabase.js.map +1 -0
  147. package/dist/esm/{operations/downloaders → core/stages/memory}/memoryDownloader.d.ts +4 -4
  148. package/dist/esm/core/stages/memory/memoryDownloader.d.ts.map +1 -0
  149. package/dist/esm/{operations/downloaders → core/stages/memory}/memoryDownloader.js +1 -1
  150. package/dist/esm/core/stages/memory/memoryDownloader.js.map +1 -0
  151. package/dist/{commonjs/operations/downloaders → esm/core/stages}/serverDownloader.d.ts +8 -6
  152. package/dist/esm/core/stages/serverDownloader.d.ts.map +1 -0
  153. package/dist/esm/{operations/downloaders → core/stages}/serverDownloader.js +98 -49
  154. package/dist/esm/core/stages/serverDownloader.js.map +1 -0
  155. package/dist/esm/core/traverser.d.ts.map +1 -0
  156. package/dist/esm/{operations → core}/traverser.js +1 -1
  157. package/dist/esm/core/traverser.js.map +1 -0
  158. package/dist/esm/deferment/MemoryCache.d.ts +35 -0
  159. package/dist/esm/deferment/MemoryCache.d.ts.map +1 -0
  160. package/dist/esm/deferment/MemoryCache.js +157 -0
  161. package/dist/esm/deferment/MemoryCache.js.map +1 -0
  162. package/dist/esm/deferment/MemoryCache.test.d.ts +2 -0
  163. package/dist/esm/deferment/MemoryCache.test.d.ts.map +1 -0
  164. package/dist/esm/deferment/MemoryCache.test.js +151 -0
  165. package/dist/esm/deferment/MemoryCache.test.js.map +1 -0
  166. package/dist/esm/deferment/defermentManager.d.ts +32 -0
  167. package/dist/esm/deferment/defermentManager.d.ts.map +1 -0
  168. package/dist/esm/deferment/defermentManager.js +80 -0
  169. package/dist/esm/deferment/defermentManager.js.map +1 -0
  170. package/dist/esm/deferment/defermentManager.test.d.ts +2 -0
  171. package/dist/esm/deferment/defermentManager.test.d.ts.map +1 -0
  172. package/dist/esm/deferment/defermentManager.test.js +191 -0
  173. package/dist/esm/deferment/defermentManager.test.js.map +1 -0
  174. package/dist/esm/deferment/deferredBase.d.ts +12 -0
  175. package/dist/esm/deferment/deferredBase.d.ts.map +1 -0
  176. package/dist/esm/deferment/deferredBase.js +23 -0
  177. package/dist/esm/deferment/deferredBase.js.map +1 -0
  178. package/dist/esm/index.d.ts +4 -2
  179. package/dist/esm/index.d.ts.map +1 -1
  180. package/dist/esm/index.js +3 -2
  181. package/dist/esm/index.js.map +1 -1
  182. package/dist/esm/{helpers → queues}/aggregateQueue.d.ts +2 -1
  183. package/dist/esm/queues/aggregateQueue.d.ts.map +1 -0
  184. package/dist/esm/{helpers → queues}/aggregateQueue.js +4 -0
  185. package/dist/esm/queues/aggregateQueue.js.map +1 -0
  186. package/dist/{commonjs/helpers → esm/queues}/asyncGeneratorQueue.d.ts +1 -1
  187. package/dist/esm/queues/asyncGeneratorQueue.d.ts.map +1 -0
  188. package/dist/esm/{helpers → queues}/asyncGeneratorQueue.js +2 -1
  189. package/dist/esm/queues/asyncGeneratorQueue.js.map +1 -0
  190. package/dist/esm/{helpers → queues}/batchingQueue.d.ts +4 -1
  191. package/dist/esm/queues/batchingQueue.d.ts.map +1 -0
  192. package/dist/esm/queues/batchingQueue.dispose.test.d.ts +2 -0
  193. package/dist/esm/queues/batchingQueue.dispose.test.d.ts.map +1 -0
  194. package/dist/esm/queues/batchingQueue.dispose.test.js +57 -0
  195. package/dist/esm/queues/batchingQueue.dispose.test.js.map +1 -0
  196. package/dist/esm/queues/batchingQueue.js +122 -0
  197. package/dist/esm/queues/batchingQueue.js.map +1 -0
  198. package/dist/esm/queues/batchingQueue.test.d.ts +2 -0
  199. package/dist/esm/queues/batchingQueue.test.d.ts.map +1 -0
  200. package/dist/esm/queues/batchingQueue.test.js +231 -0
  201. package/dist/esm/queues/batchingQueue.test.js.map +1 -0
  202. package/dist/{commonjs/helpers → esm/queues}/bufferQueue.d.ts +1 -0
  203. package/dist/esm/queues/bufferQueue.d.ts.map +1 -0
  204. package/dist/esm/{helpers → queues}/bufferQueue.js +3 -0
  205. package/dist/esm/queues/bufferQueue.js.map +1 -0
  206. package/dist/esm/{helpers → queues}/keyedQueue.d.ts +1 -0
  207. package/dist/esm/queues/keyedQueue.d.ts.map +1 -0
  208. package/dist/esm/{helpers → queues}/keyedQueue.js +11 -0
  209. package/dist/esm/queues/keyedQueue.js.map +1 -0
  210. package/dist/esm/queues/keyedQueue.test.d.ts +2 -0
  211. package/dist/esm/queues/keyedQueue.test.d.ts.map +1 -0
  212. package/dist/esm/queues/keyedQueue.test.js +113 -0
  213. package/dist/esm/queues/keyedQueue.test.js.map +1 -0
  214. package/dist/esm/queues/queue.d.ts +5 -0
  215. package/dist/esm/queues/queue.d.ts.map +1 -0
  216. package/dist/esm/{helpers → queues}/queue.js.map +1 -1
  217. package/dist/esm/types/functions.d.ts +21 -0
  218. package/dist/esm/types/functions.d.ts.map +1 -0
  219. package/dist/esm/types/functions.js +83 -0
  220. package/dist/esm/types/functions.js.map +1 -0
  221. package/dist/esm/types/types.d.ts +6 -7
  222. package/dist/esm/types/types.d.ts.map +1 -1
  223. package/dist/esm/types/types.js +1 -32
  224. package/dist/esm/types/types.js.map +1 -1
  225. package/package.json +5 -3
  226. package/src/{operations → core}/interfaces.ts +5 -5
  227. package/src/{operations → core}/objectLoader2.spec.ts +31 -11
  228. package/src/core/objectLoader2.ts +152 -0
  229. package/src/core/objectLoader2Factory.test.ts +135 -0
  230. package/src/core/objectLoader2Factory.ts +113 -0
  231. package/src/{operations → core}/options.ts +4 -1
  232. package/src/{operations/databases → core/stages}/__snapshots__/indexedDatabase.spec.ts.snap +4 -4
  233. package/src/{operations/downloaders → core/stages}/__snapshots__/serverDownloader.spec.ts.snap +25 -0
  234. package/src/{helpers → core/stages}/cacheReader.spec.ts +12 -7
  235. package/src/core/stages/cacheReader.ts +88 -0
  236. package/src/core/stages/cacheWriter.spec.ts +213 -0
  237. package/src/core/stages/cacheWriter.ts +64 -0
  238. package/src/{operations/databases → core/stages}/indexedDatabase.spec.ts +12 -8
  239. package/src/core/stages/indexedDatabase.ts +178 -0
  240. package/src/{operations/databases → core/stages/memory}/memoryDatabase.spec.ts +7 -7
  241. package/src/{operations/databases → core/stages/memory}/memoryDatabase.ts +9 -6
  242. package/src/{operations/downloaders → core/stages/memory}/memoryDownloader.spec.ts +5 -5
  243. package/src/{operations/downloaders → core/stages/memory}/memoryDownloader.ts +4 -4
  244. package/src/core/stages/serverDownloader.spec.ts +382 -0
  245. package/src/{operations/downloaders → core/stages}/serverDownloader.ts +115 -52
  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 +225 -0
  250. package/src/deferment/defermentManager.ts +95 -0
  251. package/src/deferment/deferredBase.ts +29 -0
  252. package/src/index.ts +4 -2
  253. package/src/{helpers → queues}/aggregateQueue.ts +5 -1
  254. package/src/{helpers → queues}/asyncGeneratorQueue.ts +2 -1
  255. package/src/queues/batchingQueue.dispose.test.ts +72 -0
  256. package/src/queues/batchingQueue.test.ts +270 -0
  257. package/src/queues/batchingQueue.ts +140 -0
  258. package/src/{helpers → queues}/bufferQueue.ts +3 -0
  259. package/src/queues/keyedQueue.test.ts +146 -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 +2 -2
  263. package/src/types/functions.spec.ts +155 -0
  264. package/src/types/functions.ts +116 -0
  265. package/src/types/types.ts +5 -50
  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 +0 -12
  271. package/dist/commonjs/helpers/batchedPool.d.ts.map +0 -1
  272. package/dist/commonjs/helpers/batchedPool.js +0 -45
  273. package/dist/commonjs/helpers/batchedPool.js.map +0 -1
  274. package/dist/commonjs/helpers/batchingQueue.d.ts.map +0 -1
  275. package/dist/commonjs/helpers/batchingQueue.js +0 -77
  276. package/dist/commonjs/helpers/batchingQueue.js.map +0 -1
  277. package/dist/commonjs/helpers/bufferQueue.d.ts.map +0 -1
  278. package/dist/commonjs/helpers/bufferQueue.js.map +0 -1
  279. package/dist/commonjs/helpers/cachePump.d.ts +0 -22
  280. package/dist/commonjs/helpers/cachePump.d.ts.map +0 -1
  281. package/dist/commonjs/helpers/cachePump.js +0 -86
  282. package/dist/commonjs/helpers/cachePump.js.map +0 -1
  283. package/dist/commonjs/helpers/cacheReader.d.ts +0 -14
  284. package/dist/commonjs/helpers/cacheReader.d.ts.map +0 -1
  285. package/dist/commonjs/helpers/cacheReader.js +0 -58
  286. package/dist/commonjs/helpers/cacheReader.js.map +0 -1
  287. package/dist/commonjs/helpers/defermentManager.d.ts +0 -28
  288. package/dist/commonjs/helpers/defermentManager.d.ts.map +0 -1
  289. package/dist/commonjs/helpers/defermentManager.js +0 -150
  290. package/dist/commonjs/helpers/defermentManager.js.map +0 -1
  291. package/dist/commonjs/helpers/deferredBase.d.ts +0 -19
  292. package/dist/commonjs/helpers/deferredBase.d.ts.map +0 -1
  293. package/dist/commonjs/helpers/deferredBase.js +0 -51
  294. package/dist/commonjs/helpers/deferredBase.js.map +0 -1
  295. package/dist/commonjs/helpers/keyedQueue.d.ts.map +0 -1
  296. package/dist/commonjs/helpers/keyedQueue.js.map +0 -1
  297. package/dist/commonjs/helpers/memoryPump.d.ts +0 -15
  298. package/dist/commonjs/helpers/memoryPump.d.ts.map +0 -1
  299. package/dist/commonjs/helpers/memoryPump.js +0 -34
  300. package/dist/commonjs/helpers/memoryPump.js.map +0 -1
  301. package/dist/commonjs/helpers/pump.d.ts +0 -8
  302. package/dist/commonjs/helpers/pump.d.ts.map +0 -1
  303. package/dist/commonjs/helpers/pump.js +0 -3
  304. package/dist/commonjs/helpers/pump.js.map +0 -1
  305. package/dist/commonjs/helpers/queue.d.ts +0 -4
  306. package/dist/commonjs/helpers/queue.d.ts.map +0 -1
  307. package/dist/commonjs/operations/databases/indexedDatabase.d.ts +0 -27
  308. package/dist/commonjs/operations/databases/indexedDatabase.d.ts.map +0 -1
  309. package/dist/commonjs/operations/databases/indexedDatabase.js +0 -98
  310. package/dist/commonjs/operations/databases/indexedDatabase.js.map +0 -1
  311. package/dist/commonjs/operations/databases/memoryDatabase.d.ts +0 -13
  312. package/dist/commonjs/operations/databases/memoryDatabase.d.ts.map +0 -1
  313. package/dist/commonjs/operations/databases/memoryDatabase.js.map +0 -1
  314. package/dist/commonjs/operations/downloaders/memoryDownloader.d.ts.map +0 -1
  315. package/dist/commonjs/operations/downloaders/memoryDownloader.js.map +0 -1
  316. package/dist/commonjs/operations/downloaders/serverDownloader.d.ts.map +0 -1
  317. package/dist/commonjs/operations/downloaders/serverDownloader.js.map +0 -1
  318. package/dist/commonjs/operations/interfaces.d.ts.map +0 -1
  319. package/dist/commonjs/operations/interfaces.js.map +0 -1
  320. package/dist/commonjs/operations/objectLoader2.d.ts.map +0 -1
  321. package/dist/commonjs/operations/objectLoader2.js +0 -101
  322. package/dist/commonjs/operations/objectLoader2.js.map +0 -1
  323. package/dist/commonjs/operations/objectLoader2Factory.d.ts.map +0 -1
  324. package/dist/commonjs/operations/objectLoader2Factory.js +0 -68
  325. package/dist/commonjs/operations/objectLoader2Factory.js.map +0 -1
  326. package/dist/commonjs/operations/options.d.ts.map +0 -1
  327. package/dist/commonjs/operations/traverser.d.ts.map +0 -1
  328. package/dist/commonjs/operations/traverser.js.map +0 -1
  329. package/dist/esm/helpers/aggregateQueue.d.ts.map +0 -1
  330. package/dist/esm/helpers/aggregateQueue.js.map +0 -1
  331. package/dist/esm/helpers/asyncGeneratorQueue.d.ts.map +0 -1
  332. package/dist/esm/helpers/asyncGeneratorQueue.js.map +0 -1
  333. package/dist/esm/helpers/batchedPool.d.ts +0 -12
  334. package/dist/esm/helpers/batchedPool.d.ts.map +0 -1
  335. package/dist/esm/helpers/batchedPool.js +0 -42
  336. package/dist/esm/helpers/batchedPool.js.map +0 -1
  337. package/dist/esm/helpers/batchingQueue.d.ts.map +0 -1
  338. package/dist/esm/helpers/batchingQueue.js +0 -71
  339. package/dist/esm/helpers/batchingQueue.js.map +0 -1
  340. package/dist/esm/helpers/bufferQueue.d.ts.map +0 -1
  341. package/dist/esm/helpers/bufferQueue.js.map +0 -1
  342. package/dist/esm/helpers/cachePump.d.ts +0 -22
  343. package/dist/esm/helpers/cachePump.d.ts.map +0 -1
  344. package/dist/esm/helpers/cachePump.js +0 -79
  345. package/dist/esm/helpers/cachePump.js.map +0 -1
  346. package/dist/esm/helpers/cacheReader.d.ts +0 -14
  347. package/dist/esm/helpers/cacheReader.d.ts.map +0 -1
  348. package/dist/esm/helpers/cacheReader.js +0 -51
  349. package/dist/esm/helpers/cacheReader.js.map +0 -1
  350. package/dist/esm/helpers/defermentManager.d.ts +0 -28
  351. package/dist/esm/helpers/defermentManager.d.ts.map +0 -1
  352. package/dist/esm/helpers/defermentManager.js +0 -146
  353. package/dist/esm/helpers/defermentManager.js.map +0 -1
  354. package/dist/esm/helpers/deferredBase.d.ts +0 -19
  355. package/dist/esm/helpers/deferredBase.d.ts.map +0 -1
  356. package/dist/esm/helpers/deferredBase.js +0 -47
  357. package/dist/esm/helpers/deferredBase.js.map +0 -1
  358. package/dist/esm/helpers/keyedQueue.d.ts.map +0 -1
  359. package/dist/esm/helpers/keyedQueue.js.map +0 -1
  360. package/dist/esm/helpers/memoryPump.d.ts +0 -15
  361. package/dist/esm/helpers/memoryPump.d.ts.map +0 -1
  362. package/dist/esm/helpers/memoryPump.js +0 -30
  363. package/dist/esm/helpers/memoryPump.js.map +0 -1
  364. package/dist/esm/helpers/pump.d.ts +0 -8
  365. package/dist/esm/helpers/pump.d.ts.map +0 -1
  366. package/dist/esm/helpers/pump.js +0 -2
  367. package/dist/esm/helpers/pump.js.map +0 -1
  368. package/dist/esm/helpers/queue.d.ts +0 -4
  369. package/dist/esm/helpers/queue.d.ts.map +0 -1
  370. package/dist/esm/operations/databases/indexedDatabase.d.ts +0 -27
  371. package/dist/esm/operations/databases/indexedDatabase.d.ts.map +0 -1
  372. package/dist/esm/operations/databases/indexedDatabase.js +0 -93
  373. package/dist/esm/operations/databases/indexedDatabase.js.map +0 -1
  374. package/dist/esm/operations/databases/memoryDatabase.d.ts +0 -13
  375. package/dist/esm/operations/databases/memoryDatabase.d.ts.map +0 -1
  376. package/dist/esm/operations/databases/memoryDatabase.js.map +0 -1
  377. package/dist/esm/operations/downloaders/memoryDownloader.d.ts.map +0 -1
  378. package/dist/esm/operations/downloaders/memoryDownloader.js.map +0 -1
  379. package/dist/esm/operations/downloaders/serverDownloader.d.ts.map +0 -1
  380. package/dist/esm/operations/downloaders/serverDownloader.js.map +0 -1
  381. package/dist/esm/operations/interfaces.d.ts.map +0 -1
  382. package/dist/esm/operations/interfaces.js.map +0 -1
  383. package/dist/esm/operations/objectLoader2.d.ts.map +0 -1
  384. package/dist/esm/operations/objectLoader2.js +0 -94
  385. package/dist/esm/operations/objectLoader2.js.map +0 -1
  386. package/dist/esm/operations/objectLoader2Factory.d.ts.map +0 -1
  387. package/dist/esm/operations/objectLoader2Factory.js +0 -61
  388. package/dist/esm/operations/objectLoader2Factory.js.map +0 -1
  389. package/dist/esm/operations/options.d.ts.map +0 -1
  390. package/dist/esm/operations/traverser.d.ts.map +0 -1
  391. package/dist/esm/operations/traverser.js.map +0 -1
  392. package/src/helpers/__snapshots__/cachePump.spec.ts.snap +0 -31
  393. package/src/helpers/__snapshots__/defermentManager.spec.ts.snap +0 -8
  394. package/src/helpers/batchedPool.ts +0 -56
  395. package/src/helpers/batchingQueue.ts +0 -85
  396. package/src/helpers/cachePump.disposal.spec.ts +0 -51
  397. package/src/helpers/cachePump.spec.ts +0 -104
  398. package/src/helpers/cachePump.ts +0 -107
  399. package/src/helpers/cacheReader.ts +0 -64
  400. package/src/helpers/defermentManager.defermentTotals.spec.ts +0 -53
  401. package/src/helpers/defermentManager.disposal.spec.ts +0 -28
  402. package/src/helpers/defermentManager.spec.ts +0 -37
  403. package/src/helpers/defermentManager.ts +0 -160
  404. package/src/helpers/deferredBase.ts +0 -55
  405. package/src/helpers/memoryPump.ts +0 -40
  406. package/src/helpers/pump.ts +0 -8
  407. package/src/operations/databases/indexedDatabase.ts +0 -126
  408. package/src/operations/downloaders/serverDownloader.spec.ts +0 -161
  409. package/src/operations/objectLoader2.ts +0 -119
  410. package/src/operations/objectLoader2Factory.ts +0 -78
  411. package/dist/commonjs/{operations → core}/interfaces.js +0 -0
  412. package/dist/commonjs/{operations → core}/options.js +0 -0
  413. package/dist/commonjs/{operations → core}/traverser.d.ts +0 -0
  414. package/dist/commonjs/{helpers → queues}/queue.js +0 -0
  415. package/dist/esm/{operations → core}/interfaces.js +0 -0
  416. package/dist/esm/{operations → core}/options.js +0 -0
  417. package/dist/esm/{operations → core}/traverser.d.ts +0 -0
  418. package/dist/esm/{helpers → queues}/queue.js +0 -0
  419. package/src/{operations → core}/__snapshots__/objectLoader2.spec.ts.snap +0 -0
  420. package/src/{operations → core}/__snapshots__/traverser.spec.ts.snap +0 -0
  421. package/src/{helpers → core/stages}/__snapshots__/cacheReader.spec.ts.snap +0 -0
  422. package/src/{operations/downloaders → core/stages/memory}/__snapshots__/memoryDownloader.spec.ts.snap +0 -0
  423. package/src/{operations → core}/traverser.spec.ts +1 -1
@@ -0,0 +1,382 @@
1
+ import { describe, expect, test } from 'vitest'
2
+ import createFetchMock from 'vitest-fetch-mock'
3
+ import { vi } from 'vitest'
4
+ import { Item } from '../../types/types.js'
5
+ import ServerDownloader from './serverDownloader.js'
6
+ import AsyncGeneratorQueue from '../../queues/asyncGeneratorQueue.js'
7
+
8
+ describe('downloader', () => {
9
+ test('download batch of one', async () => {
10
+ const fetchMocker = createFetchMock(vi)
11
+ const i: Item = { baseId: 'id', base: { id: 'id', synchronized_type: 'type' } }
12
+ fetchMocker.mockResponseOnce('id\t' + JSON.stringify(i.base) + '\n')
13
+ const gathered = new AsyncGeneratorQueue<Item>()
14
+ const downloader = new ServerDownloader({
15
+ serverUrl: 'http://synchronized.test',
16
+ streamId: 'streamId',
17
+ objectId: 'objectId',
18
+ token: 'token',
19
+ fetch: fetchMocker,
20
+ logger: (): void => {}
21
+ })
22
+ downloader.initialize({
23
+ results: gathered,
24
+ total: 1,
25
+ maxDownloadBatchWait: 200
26
+ })
27
+ downloader.add('id')
28
+ const r = []
29
+ for await (const x of gathered.consume()) {
30
+ r.push(x)
31
+ if (r.length >= 1) {
32
+ break
33
+ }
34
+ }
35
+
36
+ expect(r).toMatchSnapshot()
37
+ await downloader.disposeAsync()
38
+ })
39
+
40
+ test('download batch of two', async () => {
41
+ const fetchMocker = createFetchMock(vi)
42
+ const i1: Item = { baseId: 'id1', base: { id: 'id1', synchronized_type: 'type' } }
43
+ const i2: Item = { baseId: 'id2', base: { id: 'id2', synchronized_type: 'type' } }
44
+ fetchMocker.mockResponseOnce(
45
+ 'id1\t' + JSON.stringify(i1.base) + '\nid2\t' + JSON.stringify(i2.base) + '\n'
46
+ )
47
+
48
+ const gathered = new AsyncGeneratorQueue<Item>()
49
+ const downloader = new ServerDownloader({
50
+ serverUrl: 'http://synchronized.test',
51
+ streamId: 'streamId',
52
+ objectId: 'objectId',
53
+ token: 'token',
54
+
55
+ fetch: fetchMocker,
56
+ logger: (): void => {}
57
+ })
58
+ downloader.initialize({
59
+ results: gathered,
60
+ total: 2,
61
+ maxDownloadBatchWait: 200
62
+ })
63
+ downloader.add('id1')
64
+ downloader.add('id2')
65
+ await downloader.disposeAsync()
66
+ const r = []
67
+ for await (const x of gathered.consume()) {
68
+ r.push(x)
69
+ if (r.length >= 2) {
70
+ break
71
+ }
72
+ }
73
+
74
+ expect(r).toMatchSnapshot()
75
+ await downloader.disposeAsync()
76
+ })
77
+
78
+ test('download batch of three', async () => {
79
+ const fetchMocker = createFetchMock(vi)
80
+ const i1: Item = { baseId: 'id1', base: { id: 'id1', synchronized_type: 'type' } }
81
+ const i2: Item = { baseId: 'id2', base: { id: 'id2', synchronized_type: 'type' } }
82
+ const i3: Item = { baseId: 'id3', base: { id: 'id3', synchronized_type: 'type' } }
83
+ fetchMocker.mockResponseOnce(
84
+ 'id1\t' +
85
+ JSON.stringify(i1.base) +
86
+ '\nid2\t' +
87
+ JSON.stringify(i2.base) +
88
+ '\nid3\t' +
89
+ JSON.stringify(i3.base) +
90
+ '\n'
91
+ )
92
+
93
+ const gathered = new AsyncGeneratorQueue<Item>()
94
+ const downloader = new ServerDownloader({
95
+ serverUrl: 'http://synchronized.test',
96
+ streamId: 'streamId',
97
+ objectId: 'objectId',
98
+ token: 'token',
99
+
100
+ fetch: fetchMocker,
101
+ logger: (): void => {}
102
+ })
103
+ downloader.initialize({
104
+ results: gathered,
105
+ total: 3,
106
+ maxDownloadBatchWait: 200
107
+ })
108
+ downloader.add('id1')
109
+ downloader.add('id2')
110
+ downloader.add('id3')
111
+ await downloader.disposeAsync()
112
+ const r = []
113
+ for await (const x of gathered.consume()) {
114
+ r.push(x)
115
+ if (r.length >= 3) {
116
+ break
117
+ }
118
+ }
119
+
120
+ expect(r).toMatchSnapshot()
121
+ await downloader.disposeAsync()
122
+ })
123
+
124
+ test('download batch of three with Objects.Other.RawEncoding', async () => {
125
+ const fetchMocker = createFetchMock(vi)
126
+ const i1: Item = { baseId: 'id1', base: { id: 'id1', synchronized_type: 'type' } }
127
+ const i2: Item = {
128
+ baseId: 'id2',
129
+ base: { id: 'id2', synchronized_type: 'Objects.Other.RawEncoding' }
130
+ }
131
+ const i3: Item = { baseId: 'id3', base: { id: 'id3', synchronized_type: 'type' } }
132
+ fetchMocker.mockResponseOnce(
133
+ 'id1\t' +
134
+ JSON.stringify(i1.base) +
135
+ '\nid2\t' +
136
+ JSON.stringify(i2.base) +
137
+ '\nid3\t' +
138
+ JSON.stringify(i3.base) +
139
+ '\n'
140
+ )
141
+
142
+ const gathered = new AsyncGeneratorQueue<Item>()
143
+ const downloader = new ServerDownloader({
144
+ serverUrl: 'http://synchronized.test',
145
+ streamId: 'streamId',
146
+ objectId: 'objectId',
147
+ token: 'token',
148
+
149
+ fetch: fetchMocker,
150
+ logger: (): void => {}
151
+ })
152
+ downloader.initialize({
153
+ results: gathered,
154
+ total: 3,
155
+ maxDownloadBatchWait: 200
156
+ })
157
+ downloader.add('id1')
158
+ downloader.add('id2')
159
+ downloader.add('id3')
160
+ await downloader.disposeAsync()
161
+ const r = []
162
+ for await (const x of gathered.consume()) {
163
+ r.push(x)
164
+ if (r.length >= 3) {
165
+ break
166
+ }
167
+ }
168
+
169
+ expect(r).toMatchSnapshot()
170
+ await downloader.disposeAsync()
171
+ })
172
+
173
+ test("download Objects.Other.RawEncoding doesn't exist", async () => {
174
+ const fetchMocker = createFetchMock(vi)
175
+ const i: Item = {
176
+ baseId: 'id',
177
+ base: {
178
+ id: 'id',
179
+ synchronized_type: 'Objects.Other.RawEncoding',
180
+ __closure: { childIds: 1 }
181
+ }
182
+ }
183
+ fetchMocker.mockResponseOnce(JSON.stringify(i.base))
184
+ const downloader = new ServerDownloader({
185
+ serverUrl: 'http://synchronized.test',
186
+ streamId: 'streamId',
187
+ objectId: i.baseId,
188
+ token: 'token',
189
+
190
+ fetch: fetchMocker,
191
+ logger: (): void => {}
192
+ })
193
+ await expect(downloader.downloadSingle()).rejects.toThrow()
194
+ await downloader.disposeAsync()
195
+ })
196
+
197
+ test('download single exists', async () => {
198
+ const fetchMocker = createFetchMock(vi)
199
+ const i: Item = {
200
+ baseId: 'id',
201
+ base: { id: 'id', synchronized_type: 'type', __closure: { childIds: 1 } }
202
+ }
203
+ fetchMocker.mockResponseOnce(JSON.stringify(i.base))
204
+ const downloader = new ServerDownloader({
205
+ serverUrl: 'http://synchronized.test',
206
+ streamId: 'streamId',
207
+ objectId: i.baseId,
208
+ token: 'token',
209
+
210
+ fetch: fetchMocker,
211
+ logger: (): void => {}
212
+ })
213
+ const x = await downloader.downloadSingle()
214
+ expect(x).toMatchSnapshot()
215
+ await downloader.disposeAsync()
216
+ })
217
+
218
+ test('add extra header', async () => {
219
+ const fetchMocker = createFetchMock(vi)
220
+ const i: Item = {
221
+ baseId: 'id',
222
+ base: { id: 'id', synchronized_type: 'type', __closure: { childIds: 1 } }
223
+ }
224
+ fetchMocker.mockResponseIf(
225
+ (req) => req.headers.get('x-test') === 'asdf',
226
+ JSON.stringify(i.base)
227
+ )
228
+ const headers = new Headers()
229
+ headers.set('x-test', 'asdf')
230
+ const downloader = new ServerDownloader({
231
+ serverUrl: 'http://synchronized.test',
232
+ headers,
233
+ streamId: 'streamId',
234
+ objectId: i.baseId,
235
+ token: 'token',
236
+
237
+ fetch: fetchMocker,
238
+ logger: (): void => {}
239
+ })
240
+ const x = await downloader.downloadSingle()
241
+ expect(x).toMatchSnapshot()
242
+ await downloader.disposeAsync()
243
+ })
244
+
245
+ test('can dispose used', async () => {
246
+ const fetchMocker = createFetchMock(vi)
247
+ const headers = new Headers()
248
+ const downloader = new ServerDownloader({
249
+ serverUrl: 'http://synchronized.test',
250
+ headers,
251
+ streamId: 'streamId',
252
+ objectId: 'objectId',
253
+ token: 'token',
254
+
255
+ fetch: fetchMocker,
256
+ logger: (): void => {}
257
+ })
258
+ await downloader.disposeAsync()
259
+ })
260
+
261
+ test('nothing is frozen when validateResponse returns 403', async () => {
262
+ const fetchMocker = createFetchMock(vi)
263
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
264
+
265
+ // Mock a 403 Forbidden response
266
+ fetchMocker.mockResponseOnce('', { status: 403, statusText: 'Forbidden' })
267
+
268
+ const gathered = new AsyncGeneratorQueue<Item>()
269
+ const downloader = new ServerDownloader({
270
+ serverUrl: 'http://synchronized.test',
271
+ streamId: 'streamId',
272
+ objectId: 'objectId',
273
+ token: 'invalid-token',
274
+ fetch: fetchMocker,
275
+ logger: (): void => {}
276
+ })
277
+
278
+ try {
279
+ downloader.initialize({
280
+ results: gathered,
281
+ total: 2,
282
+ maxDownloadBatchWait: 100
283
+ })
284
+
285
+ // Add items to trigger batch processing
286
+ downloader.add('id1')
287
+ downloader.add('id2')
288
+
289
+ // Wait for the batch to be processed and fail with 403
290
+ await new Promise((resolve) => setTimeout(resolve, 200))
291
+
292
+ // Verify that the error was logged (indicating the batch processing failed)
293
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
294
+ 'Batch processing failed:',
295
+ expect.any(Error)
296
+ )
297
+
298
+ // The key test: verify we can still dispose the downloader properly
299
+ // This ensures the system isn't frozen and can clean up resources
300
+ const disposePromise = downloader.disposeAsync()
301
+
302
+ // Add a timeout to ensure disposal doesn't hang indefinitely
303
+ const timeoutPromise = new Promise((_, reject) => {
304
+ setTimeout(() => reject(new Error('Disposal timed out')), 5000)
305
+ })
306
+
307
+ // This should complete without timing out or throwing
308
+ await Promise.race([disposePromise, timeoutPromise])
309
+
310
+ // Additional verification: the batching queue should be marked as disposed
311
+ // We can't directly access the private field, but we can verify disposal completed
312
+ expect(true).toBe(true) // If we reach here, disposal succeeded
313
+ } finally {
314
+ consoleErrorSpy.mockRestore()
315
+ }
316
+ })
317
+
318
+ test('system remains functional after 403 error and can be properly cleaned up', async () => {
319
+ const fetchMocker = createFetchMock(vi)
320
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
321
+
322
+ // First call returns 403, subsequent calls should not be made due to queue disposal
323
+ fetchMocker.mockResponseOnce('', { status: 403, statusText: 'Forbidden' })
324
+
325
+ const gathered = new AsyncGeneratorQueue<Item>()
326
+ const downloader = new ServerDownloader({
327
+ serverUrl: 'http://synchronized.test',
328
+ streamId: 'streamId',
329
+ objectId: 'objectId',
330
+ token: 'invalid-token',
331
+ fetch: fetchMocker,
332
+ logger: (): void => {}
333
+ })
334
+
335
+ try {
336
+ downloader.initialize({
337
+ results: gathered,
338
+ total: 5,
339
+ maxDownloadBatchWait: 50
340
+ })
341
+
342
+ // Add first batch that will trigger the 403 error
343
+ downloader.add('id1')
344
+ downloader.add('id2')
345
+
346
+ // Wait for first batch to fail
347
+ await new Promise((resolve) => setTimeout(resolve, 100))
348
+
349
+ // Verify error was logged
350
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
351
+ 'Batch processing failed:',
352
+ expect.any(Error)
353
+ )
354
+
355
+ // Try to add more items after the failure
356
+ // These should be ignored since the queue is now disposed
357
+ downloader.add('id3')
358
+ downloader.add('id4')
359
+ downloader.add('id5')
360
+
361
+ // Wait a bit more to ensure no additional processing attempts
362
+ await new Promise((resolve) => setTimeout(resolve, 100))
363
+
364
+ // Note: The batching queue might make multiple attempts before disposal
365
+ // The key is that disposal should still work regardless of how many calls were made
366
+ expect(fetchMocker).toHaveBeenCalled()
367
+
368
+ // Critical test: disposal should complete without hanging
369
+ const start = Date.now()
370
+ await downloader.disposeAsync()
371
+ const elapsed = Date.now() - start
372
+
373
+ // Disposal should be quick (under 1 second) and not hang
374
+ expect(elapsed).toBeLessThan(1000)
375
+
376
+ // Verify that the results queue can also be disposed properly
377
+ await gathered.disposeAsync()
378
+ } finally {
379
+ consoleErrorSpy.mockRestore()
380
+ }
381
+ })
382
+ })
@@ -1,7 +1,8 @@
1
- import BatchedPool from '../../helpers/batchedPool.js'
2
- import Queue from '../../helpers/queue.js'
1
+ import BatchingQueue from '../../queues/batchingQueue.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 { CustomLogger, Fetcher, indexOf, isBase, take } from '../../types/functions.js'
5
+ import { Item, ObjectAttributeMask } from '../../types/types.js'
5
6
  import { Downloader } from '../interfaces.js'
6
7
 
7
8
  export interface ServerDownloaderOptions {
@@ -10,9 +11,14 @@ export interface ServerDownloaderOptions {
10
11
  objectId: string
11
12
  token?: string
12
13
  headers?: Headers
14
+ logger: CustomLogger
13
15
  fetch?: Fetcher
16
+ attributeMask?: ObjectAttributeMask
17
+ objectTypeMask?: string[] // Temporary until server filters are elevated and ready
14
18
  }
15
19
 
20
+ const MAX_SAFARI_DECODE_BYTES = 2 * 1024 * 1024 * 1024 - 1024 * 1024 // 2GB minus a margin
21
+
16
22
  export default class ServerDownloader implements Downloader {
17
23
  #requestUrlRootObj: string
18
24
  #requestUrlChildren: string
@@ -20,12 +26,19 @@ export default class ServerDownloader implements Downloader {
20
26
  #options: ServerDownloaderOptions
21
27
  #fetch: Fetcher
22
28
  #results?: Queue<Item>
29
+ #total?: number
30
+ #logger: CustomLogger
31
+
32
+ #downloadQueue?: BatchingQueue<string>
33
+ #decoder = new TextDecoder('utf-8', { fatal: true })
34
+ #decodedBytesCount = 0
23
35
 
24
- #downloadQueue?: BatchedPool<string>
25
- #decoder = new TextDecoder()
36
+ #rawStrings: Array<string> = []
37
+ #rawEncodings: Array<Uint8Array> = []
26
38
 
27
39
  constructor(options: ServerDownloaderOptions) {
28
40
  this.#options = options
41
+ this.#logger = options.logger
29
42
  this.#fetch =
30
43
  options.fetch ?? ((...args): Promise<Response> => globalThis.fetch(...args))
31
44
 
@@ -40,32 +53,34 @@ export default class ServerDownloader implements Downloader {
40
53
  if (this.#options.token) {
41
54
  this.#headers['Authorization'] = `Bearer ${this.#options.token}`
42
55
  }
43
- this.#requestUrlChildren = `${this.#options.serverUrl}/api/getobjects/${
56
+ this.#requestUrlChildren = `${this.#options.serverUrl}/api/v2/projects/${
44
57
  this.#options.streamId
45
- }`
58
+ }/object-stream/`
59
+
46
60
  this.#requestUrlRootObj = `${this.#options.serverUrl}/objects/${
47
61
  this.#options.streamId
48
62
  }/${this.#options.objectId}/single`
49
- }
50
63
 
51
- #getDownloadCountAndSizes(total: number): number[] {
52
- if (total <= 50) {
53
- return [total]
64
+ const encoder = new TextEncoder()
65
+ if (options.objectTypeMask) {
66
+ this.#rawStrings.push(...options.objectTypeMask)
67
+ this.#rawEncodings.push(
68
+ ...options.objectTypeMask.map((val) => encoder.encode(val))
69
+ )
54
70
  }
55
-
56
- return [10000, 25000, 10000, 1000]
57
71
  }
58
72
 
59
- initializePool(params: {
73
+ initialize(params: {
60
74
  results: Queue<Item>
61
75
  total: number
62
76
  maxDownloadBatchWait?: number
63
77
  }): void {
64
- const { results, total } = params
78
+ const { results, total, maxDownloadBatchWait } = params
65
79
  this.#results = results
66
- this.#downloadQueue = new BatchedPool<string>({
67
- concurrencyAndSizes: this.#getDownloadCountAndSizes(total),
68
- maxWaitTime: params.maxDownloadBatchWait,
80
+ this.#total = total
81
+ this.#downloadQueue = new BatchingQueue<string>({
82
+ batchSize: 15000, // 15k is a good number for most cases
83
+ maxWaitTime: maxDownloadBatchWait ?? 1000, // 1 second
69
84
  processFunction: (batch: string[]): Promise<void> =>
70
85
  this.downloadBatch({
71
86
  batch,
@@ -75,46 +90,47 @@ export default class ServerDownloader implements Downloader {
75
90
  })
76
91
  }
77
92
 
78
- #getPool(): BatchedPool<string> {
79
- if (this.#downloadQueue) {
80
- return this.#downloadQueue
81
- }
82
- throw new Error('Download pool is not initialized')
93
+ add(id: string): void {
94
+ this.#downloadQueue?.add(id, id)
83
95
  }
84
96
 
85
- add(id: string): void {
86
- this.#getPool().add(id)
97
+ /*
98
+ 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.
99
+
100
+ 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.
101
+
102
+ 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.
103
+ */
104
+ decodeChunk(chunkBuffer: Uint8Array): string {
105
+ if (this.#decodedBytesCount + chunkBuffer.byteLength > MAX_SAFARI_DECODE_BYTES) {
106
+ // Safari is approaching its limit, create a new decoder
107
+ this.#decoder = new TextDecoder('utf-8', { fatal: true })
108
+ this.#decodedBytesCount = 0 // Reset counter for the new decoder
109
+ }
110
+ const decodedText = this.#decoder.decode(chunkBuffer)
111
+ this.#decodedBytesCount += chunkBuffer.byteLength
112
+ return decodedText
87
113
  }
88
114
 
89
115
  async disposeAsync(): Promise<void> {
90
116
  await this.#downloadQueue?.disposeAsync()
91
117
  }
92
118
 
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
- }
105
- }
106
-
107
119
  async downloadBatch(params: {
108
120
  batch: string[]
109
121
  url: string
110
122
  headers: HeadersInit
111
123
  }): Promise<void> {
112
124
  const { batch, url, headers } = params
125
+
126
+ const start = performance.now()
127
+ this.#logger(`Downloading batch of ${batch.length} items...`)
128
+ const attributeMask = this.#options.attributeMask
113
129
  const keys = new Set<string>(batch)
114
130
  const response = await this.#fetch(url, {
115
131
  method: 'POST',
116
132
  headers: { ...headers, 'Content-Type': 'application/json' },
117
- body: JSON.stringify({ objects: JSON.stringify(batch) })
133
+ body: JSON.stringify({ objectIds: batch, attributeMask })
118
134
  })
119
135
 
120
136
  this.#validateResponse(response)
@@ -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,23 @@ 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
+ }
165
+ this.#logger(
166
+ `Downloaded batch of ${batch.length} items in ${performance.now() - start}ms`
167
+ )
145
168
  }
146
169
 
147
- async processArray(
170
+ async #processArray(
148
171
  leftover: Uint8Array,
149
172
  value: Uint8Array,
150
173
  keys: Set<string>,
151
174
  callback: () => Promise<void>
152
175
  ): Promise<Uint8Array> {
153
176
  //this concat will allocate a new array
154
- const combined = this.concatUint8Arrays(leftover, value)
177
+ const combined = this.#concatUint8Arrays(leftover, value)
155
178
  let start = 0
156
179
 
157
180
  //subarray doesn't allocate
@@ -159,34 +182,68 @@ export default class ServerDownloader implements Downloader {
159
182
  if (combined[i] === 0x0a) {
160
183
  const line = combined.subarray(start, i) // line without \n
161
184
  //strings are allocated here
162
- const item = this.processLine(line)
163
- this.#results?.add(item)
185
+ const item = this.#processLine(line)
164
186
  start = i + 1
165
187
  await callback()
166
188
  keys.delete(item.baseId)
189
+ this.#results?.add(item)
167
190
  }
168
191
  }
169
192
  return combined.subarray(start) // carry over remainder
170
193
  }
171
194
 
172
- processLine(line: Uint8Array): Item {
195
+ #processLine(line: Uint8Array): Item {
173
196
  for (let i = 0; i < line.length; i++) {
174
197
  if (line[i] === 0x09) {
175
198
  //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)
199
+ const baseId = this.decodeChunk(line.subarray(0, i))
200
+ const jsonBytes = line.subarray(i + 1)
201
+
202
+ if (!this.#isValidBytes(jsonBytes)) {
203
+ return { baseId, base: undefined }
204
+ }
205
+ const base = this.decodeChunk(jsonBytes)
179
206
  const item = this.#processJson(baseId, base)
180
- item.size = json.length
207
+ item.size = jsonBytes.length
181
208
  return item
182
209
  }
183
210
  }
184
211
  throw new ObjectLoaderRuntimeError(
185
- 'Invalid line format: ' + this.#decoder.decode(line)
212
+ 'Invalid line format in response: ' + this.decodeChunk(line)
186
213
  )
187
214
  }
188
215
 
189
- concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array {
216
+ #processJson(baseId: string, unparsedBase: string): Item {
217
+ let base: unknown
218
+ try {
219
+ base = JSON.parse(unparsedBase)
220
+ } catch (e: unknown) {
221
+ throw new Error(`Error parsing object ${baseId}: ${(e as Error).message}`)
222
+ }
223
+ if (isBase(base)) {
224
+ return { baseId, base }
225
+ } else {
226
+ throw new ObjectLoaderRuntimeError(`${baseId} is not a base`)
227
+ }
228
+ }
229
+
230
+ #isValidString(json: string): boolean {
231
+ for (const rawString of this.#rawStrings)
232
+ if (json.includes(rawString)) {
233
+ return false
234
+ }
235
+ return true
236
+ }
237
+
238
+ #isValidBytes(json: Uint8Array): boolean {
239
+ for (const rawEncoding of this.#rawEncodings)
240
+ if (indexOf(json, rawEncoding) !== -1) {
241
+ return false
242
+ }
243
+ return true
244
+ }
245
+
246
+ #concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array {
190
247
  const c = new Uint8Array(a.length + b.length)
191
248
  c.set(a, 0)
192
249
  c.set(b, a.length)
@@ -199,7 +256,13 @@ export default class ServerDownloader implements Downloader {
199
256
  })
200
257
  this.#validateResponse(response)
201
258
  const responseText = await response.text()
259
+ if (!this.#isValidString(responseText)) {
260
+ throw new ObjectLoaderRuntimeError('Invalid base object')
261
+ }
202
262
  const item = this.#processJson(this.#options.objectId, responseText)
263
+ if (!item.base) {
264
+ throw new ObjectLoaderRuntimeError('Invalid base object')
265
+ }
203
266
  item.size = 0
204
267
  return item
205
268
  }
@@ -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'