@warp-drive-mirror/experiments 0.0.1-alpha.97

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 (41) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +9 -0
  3. package/NCC-1701-a-blue.svg +4 -0
  4. package/NCC-1701-a.svg +4 -0
  5. package/README.md +33 -0
  6. package/dist/data-worker.js +281 -0
  7. package/dist/data-worker.js.map +1 -0
  8. package/dist/document-storage.js +243 -0
  9. package/dist/document-storage.js.map +1 -0
  10. package/dist/persisted-cache.js +559 -0
  11. package/dist/persisted-cache.js.map +1 -0
  12. package/dist/worker-fetch.js +149 -0
  13. package/dist/worker-fetch.js.map +1 -0
  14. package/package.json +82 -0
  15. package/unstable-preview-types/data-worker/cache-handler.d.ts +11 -0
  16. package/unstable-preview-types/data-worker/cache-handler.d.ts.map +1 -0
  17. package/unstable-preview-types/data-worker/fetch.d.ts +37 -0
  18. package/unstable-preview-types/data-worker/fetch.d.ts.map +1 -0
  19. package/unstable-preview-types/data-worker/types.d.ts +34 -0
  20. package/unstable-preview-types/data-worker/types.d.ts.map +1 -0
  21. package/unstable-preview-types/data-worker/utils.d.ts +23 -0
  22. package/unstable-preview-types/data-worker/utils.d.ts.map +1 -0
  23. package/unstable-preview-types/data-worker/worker.d.ts +16 -0
  24. package/unstable-preview-types/data-worker/worker.d.ts.map +1 -0
  25. package/unstable-preview-types/data-worker.d.ts +5 -0
  26. package/unstable-preview-types/data-worker.d.ts.map +1 -0
  27. package/unstable-preview-types/document-storage/index.d.ts +90 -0
  28. package/unstable-preview-types/document-storage/index.d.ts.map +1 -0
  29. package/unstable-preview-types/document-storage.d.ts +4 -0
  30. package/unstable-preview-types/document-storage.d.ts.map +1 -0
  31. package/unstable-preview-types/index.d.ts +13 -0
  32. package/unstable-preview-types/persisted-cache/cache.d.ts +433 -0
  33. package/unstable-preview-types/persisted-cache/cache.d.ts.map +1 -0
  34. package/unstable-preview-types/persisted-cache/db.d.ts +25 -0
  35. package/unstable-preview-types/persisted-cache/db.d.ts.map +1 -0
  36. package/unstable-preview-types/persisted-cache/fetch.d.ts +11 -0
  37. package/unstable-preview-types/persisted-cache/fetch.d.ts.map +1 -0
  38. package/unstable-preview-types/persisted-cache.d.ts +4 -0
  39. package/unstable-preview-types/persisted-cache.d.ts.map +1 -0
  40. package/unstable-preview-types/worker-fetch.d.ts +4 -0
  41. package/unstable-preview-types/worker-fetch.d.ts.map +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ # @warp-drive-mirror/experiments Changelog
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (C) 2024 EmberData and WarpDrive contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="1200pt" height="1200pt" version="1.1" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
3
+ <path fill="#0969da" d="m1096.3 402.82c-53.148-53.008-117.12-79.516-191.93-79.516-67.488 0-126.55 21.938-177.16 65.805-50.617 43.871-80.988 98.285-91.113 163.25l53.57 4.2188c14.625 0.28125 25.449 6.75 32.48 19.406h18.984c11.809 0 17.715 5.7617 17.715 17.293s-5.9062 17.293-17.715 17.293h-17.297c-6.75 14.344-18.137 21.797-34.168 22.359l-53.57 4.6406c10.125 64.68 40.496 118.95 91.113 162.82 50.617 43.871 109.68 65.805 177.16 65.805 74.805 0 138.78-26.574 191.93-79.723 53.152-53.148 79.727-116.98 79.727-191.51 0-75.086-26.574-139.13-79.727-192.14zm-79.422 185.27c0 2.9531 2.3906 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477 0-2.9492-2.3945-5.3438-5.3477-5.3438-2.9531 0-5.3438 2.3945-5.3438 5.3438zm-104.54-111.07c0 2.9531 2.3945 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477s-2.3945-5.3438-5.3477-5.3438c-2.9492 0-5.3438 2.3906-5.3438 5.3438zm-12.473 0c0 2.9531 2.3906 5.3477 5.3438 5.3477s5.3477-2.3945 5.3477-5.3477-2.3945-5.3438-5.3477-5.3438-5.3438 2.3906-5.3438 5.3438zm117.01 123.55c0 2.9492 2.3906 5.3438 5.3438 5.3438 2.9531 0 5.3477-2.3945 5.3477-5.3438 0-2.9531-2.3945-5.3477-5.3477-5.3477-2.9531 0-5.3438 2.3945-5.3438 5.3477zm-104.54 111.66c0 2.9531 2.3945 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477s-2.3945-5.3438-5.3477-5.3438c-2.9492 0-5.3438 2.3906-5.3438 5.3438zm-12.473 0c0 2.9531 2.3906 5.3477 5.3438 5.3477s5.3477-2.3945 5.3477-5.3477-2.3945-5.3438-5.3477-5.3438-5.3438 2.3906-5.3438 5.3438zm-848-318.48c14.062-2.5312 30.934-4.5 50.621-5.9062l-46.402-0.84375zm499.86 169.15c-8.7188-2.25-18.141-8.7188-28.266-19.402l-101.23-103.35h-111.36l173.79 126.12v4.2188c21.652 6.1836 44.008 3.6562 67.07-7.5938zm47.664-148.48c-0.84375 3.3711-2.8125 6.6055-5.9062 9.6992h-5.0625l-6.3242-5.0625h-79.305v-4.6367zm-5.9062-16.031c3.0938 3.0938 5.0625 6.4688 5.9062 10.125h-96.598v-4.6406h79.305l6.3242-5.4844zm-541.62 397.78 4.2188 6.7461 46.402-0.84375c-22.5-2.2461-39.371-4.2148-50.621-5.9023zm499.86-169.15c-23.062-11.531-45.418-14.062-67.07-7.5938v4.2188l-173.79 126.12h111.36l101.23-103.77c10.406-10.684 19.828-17.012 28.266-18.98zm47.664 148.48h-96.598v-4.6406h79.305l6.3242-5.4805h5.0625c3.0938 3.6523 5.0625 7.0273 5.9062 10.121zm-5.9062 15.609h-5.0625l-6.3242-5.0625h-79.305v-4.6406h96.598c-0.84375 3.0938-2.8125 6.3281-5.9062 9.7031zm-102.5 9.6992c3.6562 1.4062 7.4531 2.1094 11.391 2.1094h64.961c24.746 0 37.121-8.4336 37.121-25.309 0-8.4375-4.6406-14.691-13.922-18.77-9.2773-4.0781-17.012-6.1172-23.199-6.1172h-64.961c-4.7812 0-8.5781 0.5625-11.391 1.6875h-333.66c-5.0625 0-28.543 1.6172-70.445 4.8516-41.902 3.2344-62.852 7.3828-62.852 12.441v11.812c0 4.5 20.949 8.5078 62.852 12.023 41.902 3.5156 65.383 5.2695 70.445 5.2695zm125.28-207.54h-42.602c-3.375 1.125-3.375 2.25 0 3.375h42.602zm-43.445 8.4375h-5.4844v-13.5h5.4844c17.152-6.1875 33.605-9.9844 49.352-11.391l4.6406-25.309 4.6406 0.42188c0.5625-4.2188 1.6875-10.262 3.375-18.137-28.684-0.5625-64.398 1.6875-107.14 6.75 3.6562 4.2148 7.4531 7.8711 11.391 10.965 4.7812 3.375 9.4219 5.625 13.918 6.75l12.656 2.9531-11.812 5.9062c-13.496 6.75-30.23 10.121-50.195 10.121-5.0625 0-8.5781-0.14062-10.547-0.42188-4.2188-0.5625-7.5898-1.1211-10.121-1.6836l-3.375-1.2656v-5.4844l-24.043-17.297c-41.34 5.625-69.32 8.5781-83.945 8.8594-31.496 0.28125-47.242 11.953-47.242 35.012 0 22.215 15.746 33.887 47.242 35.012 18.844 0.28125 46.824 3.2344 83.945 8.8594l24.043-17.297v-5.4844l3.375-1.2656c2.5312-0.84375 5.9023-1.4062 10.121-1.6875 1.9688-0.28125 5.4844-0.42187 10.547-0.42187 19.965 0 36.699 3.375 50.195 10.125l11.812 5.4844-12.656 3.375c-4.4961 0.84375-9.1367 3.0938-13.918 6.75-3.6562 2.2461-7.4531 5.7617-11.391 10.543 40.777 5.0625 76.492 7.4531 107.14 7.1719-1.6875-7.3125-2.8125-13.359-3.375-18.137h-4.6406l-4.6406-24.891c-17.434-2.25-33.887-6.043-49.352-11.387zm48.508-20.25c-12.652 1.6875-23.762 3.9375-33.324 6.75h29.105l3.7969-4.2188zm-4.2188 20.25h-29.105c9.5625 2.5312 20.672 4.7812 33.324 6.7461l-0.42188-2.5273zm136.67-8.4375c0-8.4375-4.2188-12.656-12.652-12.656h-21.516c-6.4688-12.652-16.59-18.98-30.371-18.98l-58.211-5.0625-5.9062 29.527-4.2188 5.0625v7.5938l4.2188 5.0625 5.9062 29.105 58.211-5.0625c15.469 0 26.012-7.3125 31.637-21.934h20.25c8.4336 0 12.652-4.2188 12.652-12.656zm-46.82 1.6875c0-11.531-5.9062-17.297-17.719-17.297-11.527 0-17.293 5.7656-17.293 17.297 0 11.812 5.7656 17.715 17.293 17.715 11.812 0 17.719-5.9023 17.719-17.715zm4.6406 0c0 14.902-7.4531 22.355-22.359 22.355-14.902 0-22.355-7.4531-22.355-22.355 0-14.906 7.4531-22.355 22.355-22.355 14.906 0 22.359 7.4492 22.359 22.355zm-13.922 0c0-5.625-2.8125-8.4375-8.4375-8.4375-5.3438 0-8.0156 2.8125-8.0156 8.4375s2.6719 8.4375 8.0156 8.4375c5.625 0 8.4375-2.8125 8.4375-8.4375zm4.6406 0c0 8.7188-4.3594 13.078-13.078 13.078-8.4375 0-12.652-4.3594-12.652-13.078s4.2148-13.078 12.652-13.078c8.7188 0 13.078 4.3594 13.078 13.078zm-43.871-2.1094v4.2188h-35.012v-4.2188zm258.58 2.1094c-0.5625-8.4375-4.7812-12.656-12.656-12.656-8.4336 0-12.652 4.2188-12.652 12.656s4.2188 12.656 12.652 12.656c8.4375 0 12.656-4.2188 12.656-12.656zm4.6406 0c0 11.531-5.7656 17.293-17.297 17.293-11.527 0-17.293-5.7617-17.293-17.293s5.7656-17.297 17.293-17.297c11.531 0 17.297 5.7656 17.297 17.297zm32.48 0c0-13.781-4.9219-25.59-14.766-35.434-9.5586-9.5625-21.23-14.344-35.012-14.344-15.184 0-31.777 5.7656-49.773 17.297-18.559 11.531-27.84 22.355-27.84 32.48 0 9.8438 9.2812 20.668 27.84 32.48 17.996 11.531 34.59 17.293 49.773 17.293 13.781 0 25.453-4.918 35.012-14.762 9.8438-9.5625 14.766-21.234 14.766-35.012zm5.0625 0c0 14.902-5.3438 27.699-16.031 38.387-10.684 10.684-23.621 16.027-38.809 16.027-15.746 0-33.18-6.0469-52.305-18.137-20.246-12.656-30.371-24.746-30.371-36.277s10.125-23.762 30.371-36.699c19.125-12.094 36.559-18.137 52.305-18.137 14.625 0 27.562 5.3398 38.809 16.027 10.688 10.969 16.031 23.902 16.031 38.809zm-54.418-29.105c-3.9336 0-10.262 1.6875-18.98 5.0625-7.875 3.9375-11.812 6.4648-11.812 7.5898v32.48c0 3.0938 3.9375 5.625 11.812 7.5938 7.875 3.375 14.203 5.0625 18.98 5.0625 19.406 0 29.391-9.2812 29.953-27.84 0-19.688-9.9844-29.668-29.953-29.949zm34.59 29.105v0.84375c0 21.371-11.527 32.34-34.59 32.902-4.4961 0-11.527-1.8281-21.09-5.4844-7.0312-3.9375-10.969-6.3281-11.809-7.1719-1.6875-1.4062-2.5312-3.0938-2.5312-5.0625v-32.48c0-1.4062 0.70312-2.9492 2.1094-4.6367 3.0898-2.8125 7.168-5.2031 12.23-7.1719 9-3.6562 16.031-5.4844 21.09-5.4844 22.5 0.28125 34.027 11.531 34.59 33.746zm-448.4-206.27h-333.66c-5.0625 0-28.543 1.6875-70.445 5.0625-41.902 3.375-62.852 7.5938-62.852 12.656v11.387c0 4.7812 20.949 8.8594 62.852 12.234 41.902 3.375 65.383 5.0625 70.445 5.0625h333.66c3.6562 1.4062 7.4531 2.1094 11.391 2.1094h64.961c5.3438 0 12.867-2.25 22.566-6.75 9.7031-4.5 14.555-10.547 14.555-18.137 0.28125-16.875-12.094-25.312-37.121-25.312h-64.961c-4.7812 0-8.5781 0.5625-11.391 1.6875z" fill-rule="evenodd"/>
4
+ </svg>
package/NCC-1701-a.svg ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="1200pt" height="1200pt" version="1.1" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
3
+ <path fill="#FFFFFF" d="m1096.3 402.82c-53.148-53.008-117.12-79.516-191.93-79.516-67.488 0-126.55 21.938-177.16 65.805-50.617 43.871-80.988 98.285-91.113 163.25l53.57 4.2188c14.625 0.28125 25.449 6.75 32.48 19.406h18.984c11.809 0 17.715 5.7617 17.715 17.293s-5.9062 17.293-17.715 17.293h-17.297c-6.75 14.344-18.137 21.797-34.168 22.359l-53.57 4.6406c10.125 64.68 40.496 118.95 91.113 162.82 50.617 43.871 109.68 65.805 177.16 65.805 74.805 0 138.78-26.574 191.93-79.723 53.152-53.148 79.727-116.98 79.727-191.51 0-75.086-26.574-139.13-79.727-192.14zm-79.422 185.27c0 2.9531 2.3906 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477 0-2.9492-2.3945-5.3438-5.3477-5.3438-2.9531 0-5.3438 2.3945-5.3438 5.3438zm-104.54-111.07c0 2.9531 2.3945 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477s-2.3945-5.3438-5.3477-5.3438c-2.9492 0-5.3438 2.3906-5.3438 5.3438zm-12.473 0c0 2.9531 2.3906 5.3477 5.3438 5.3477s5.3477-2.3945 5.3477-5.3477-2.3945-5.3438-5.3477-5.3438-5.3438 2.3906-5.3438 5.3438zm117.01 123.55c0 2.9492 2.3906 5.3438 5.3438 5.3438 2.9531 0 5.3477-2.3945 5.3477-5.3438 0-2.9531-2.3945-5.3477-5.3477-5.3477-2.9531 0-5.3438 2.3945-5.3438 5.3477zm-104.54 111.66c0 2.9531 2.3945 5.3477 5.3438 5.3477 2.9531 0 5.3477-2.3945 5.3477-5.3477s-2.3945-5.3438-5.3477-5.3438c-2.9492 0-5.3438 2.3906-5.3438 5.3438zm-12.473 0c0 2.9531 2.3906 5.3477 5.3438 5.3477s5.3477-2.3945 5.3477-5.3477-2.3945-5.3438-5.3477-5.3438-5.3438 2.3906-5.3438 5.3438zm-848-318.48c14.062-2.5312 30.934-4.5 50.621-5.9062l-46.402-0.84375zm499.86 169.15c-8.7188-2.25-18.141-8.7188-28.266-19.402l-101.23-103.35h-111.36l173.79 126.12v4.2188c21.652 6.1836 44.008 3.6562 67.07-7.5938zm47.664-148.48c-0.84375 3.3711-2.8125 6.6055-5.9062 9.6992h-5.0625l-6.3242-5.0625h-79.305v-4.6367zm-5.9062-16.031c3.0938 3.0938 5.0625 6.4688 5.9062 10.125h-96.598v-4.6406h79.305l6.3242-5.4844zm-541.62 397.78 4.2188 6.7461 46.402-0.84375c-22.5-2.2461-39.371-4.2148-50.621-5.9023zm499.86-169.15c-23.062-11.531-45.418-14.062-67.07-7.5938v4.2188l-173.79 126.12h111.36l101.23-103.77c10.406-10.684 19.828-17.012 28.266-18.98zm47.664 148.48h-96.598v-4.6406h79.305l6.3242-5.4805h5.0625c3.0938 3.6523 5.0625 7.0273 5.9062 10.121zm-5.9062 15.609h-5.0625l-6.3242-5.0625h-79.305v-4.6406h96.598c-0.84375 3.0938-2.8125 6.3281-5.9062 9.7031zm-102.5 9.6992c3.6562 1.4062 7.4531 2.1094 11.391 2.1094h64.961c24.746 0 37.121-8.4336 37.121-25.309 0-8.4375-4.6406-14.691-13.922-18.77-9.2773-4.0781-17.012-6.1172-23.199-6.1172h-64.961c-4.7812 0-8.5781 0.5625-11.391 1.6875h-333.66c-5.0625 0-28.543 1.6172-70.445 4.8516-41.902 3.2344-62.852 7.3828-62.852 12.441v11.812c0 4.5 20.949 8.5078 62.852 12.023 41.902 3.5156 65.383 5.2695 70.445 5.2695zm125.28-207.54h-42.602c-3.375 1.125-3.375 2.25 0 3.375h42.602zm-43.445 8.4375h-5.4844v-13.5h5.4844c17.152-6.1875 33.605-9.9844 49.352-11.391l4.6406-25.309 4.6406 0.42188c0.5625-4.2188 1.6875-10.262 3.375-18.137-28.684-0.5625-64.398 1.6875-107.14 6.75 3.6562 4.2148 7.4531 7.8711 11.391 10.965 4.7812 3.375 9.4219 5.625 13.918 6.75l12.656 2.9531-11.812 5.9062c-13.496 6.75-30.23 10.121-50.195 10.121-5.0625 0-8.5781-0.14062-10.547-0.42188-4.2188-0.5625-7.5898-1.1211-10.121-1.6836l-3.375-1.2656v-5.4844l-24.043-17.297c-41.34 5.625-69.32 8.5781-83.945 8.8594-31.496 0.28125-47.242 11.953-47.242 35.012 0 22.215 15.746 33.887 47.242 35.012 18.844 0.28125 46.824 3.2344 83.945 8.8594l24.043-17.297v-5.4844l3.375-1.2656c2.5312-0.84375 5.9023-1.4062 10.121-1.6875 1.9688-0.28125 5.4844-0.42187 10.547-0.42187 19.965 0 36.699 3.375 50.195 10.125l11.812 5.4844-12.656 3.375c-4.4961 0.84375-9.1367 3.0938-13.918 6.75-3.6562 2.2461-7.4531 5.7617-11.391 10.543 40.777 5.0625 76.492 7.4531 107.14 7.1719-1.6875-7.3125-2.8125-13.359-3.375-18.137h-4.6406l-4.6406-24.891c-17.434-2.25-33.887-6.043-49.352-11.387zm48.508-20.25c-12.652 1.6875-23.762 3.9375-33.324 6.75h29.105l3.7969-4.2188zm-4.2188 20.25h-29.105c9.5625 2.5312 20.672 4.7812 33.324 6.7461l-0.42188-2.5273zm136.67-8.4375c0-8.4375-4.2188-12.656-12.652-12.656h-21.516c-6.4688-12.652-16.59-18.98-30.371-18.98l-58.211-5.0625-5.9062 29.527-4.2188 5.0625v7.5938l4.2188 5.0625 5.9062 29.105 58.211-5.0625c15.469 0 26.012-7.3125 31.637-21.934h20.25c8.4336 0 12.652-4.2188 12.652-12.656zm-46.82 1.6875c0-11.531-5.9062-17.297-17.719-17.297-11.527 0-17.293 5.7656-17.293 17.297 0 11.812 5.7656 17.715 17.293 17.715 11.812 0 17.719-5.9023 17.719-17.715zm4.6406 0c0 14.902-7.4531 22.355-22.359 22.355-14.902 0-22.355-7.4531-22.355-22.355 0-14.906 7.4531-22.355 22.355-22.355 14.906 0 22.359 7.4492 22.359 22.355zm-13.922 0c0-5.625-2.8125-8.4375-8.4375-8.4375-5.3438 0-8.0156 2.8125-8.0156 8.4375s2.6719 8.4375 8.0156 8.4375c5.625 0 8.4375-2.8125 8.4375-8.4375zm4.6406 0c0 8.7188-4.3594 13.078-13.078 13.078-8.4375 0-12.652-4.3594-12.652-13.078s4.2148-13.078 12.652-13.078c8.7188 0 13.078 4.3594 13.078 13.078zm-43.871-2.1094v4.2188h-35.012v-4.2188zm258.58 2.1094c-0.5625-8.4375-4.7812-12.656-12.656-12.656-8.4336 0-12.652 4.2188-12.652 12.656s4.2188 12.656 12.652 12.656c8.4375 0 12.656-4.2188 12.656-12.656zm4.6406 0c0 11.531-5.7656 17.293-17.297 17.293-11.527 0-17.293-5.7617-17.293-17.293s5.7656-17.297 17.293-17.297c11.531 0 17.297 5.7656 17.297 17.297zm32.48 0c0-13.781-4.9219-25.59-14.766-35.434-9.5586-9.5625-21.23-14.344-35.012-14.344-15.184 0-31.777 5.7656-49.773 17.297-18.559 11.531-27.84 22.355-27.84 32.48 0 9.8438 9.2812 20.668 27.84 32.48 17.996 11.531 34.59 17.293 49.773 17.293 13.781 0 25.453-4.918 35.012-14.762 9.8438-9.5625 14.766-21.234 14.766-35.012zm5.0625 0c0 14.902-5.3438 27.699-16.031 38.387-10.684 10.684-23.621 16.027-38.809 16.027-15.746 0-33.18-6.0469-52.305-18.137-20.246-12.656-30.371-24.746-30.371-36.277s10.125-23.762 30.371-36.699c19.125-12.094 36.559-18.137 52.305-18.137 14.625 0 27.562 5.3398 38.809 16.027 10.688 10.969 16.031 23.902 16.031 38.809zm-54.418-29.105c-3.9336 0-10.262 1.6875-18.98 5.0625-7.875 3.9375-11.812 6.4648-11.812 7.5898v32.48c0 3.0938 3.9375 5.625 11.812 7.5938 7.875 3.375 14.203 5.0625 18.98 5.0625 19.406 0 29.391-9.2812 29.953-27.84 0-19.688-9.9844-29.668-29.953-29.949zm34.59 29.105v0.84375c0 21.371-11.527 32.34-34.59 32.902-4.4961 0-11.527-1.8281-21.09-5.4844-7.0312-3.9375-10.969-6.3281-11.809-7.1719-1.6875-1.4062-2.5312-3.0938-2.5312-5.0625v-32.48c0-1.4062 0.70312-2.9492 2.1094-4.6367 3.0898-2.8125 7.168-5.2031 12.23-7.1719 9-3.6562 16.031-5.4844 21.09-5.4844 22.5 0.28125 34.027 11.531 34.59 33.746zm-448.4-206.27h-333.66c-5.0625 0-28.543 1.6875-70.445 5.0625-41.902 3.375-62.852 7.5938-62.852 12.656v11.387c0 4.7812 20.949 8.8594 62.852 12.234 41.902 3.375 65.383 5.0625 70.445 5.0625h333.66c3.6562 1.4062 7.4531 2.1094 11.391 2.1094h64.961c5.3438 0 12.867-2.25 22.566-6.75 9.7031-4.5 14.555-10.547 14.555-18.137 0.28125-16.875-12.094-25.312-37.121-25.312h-64.961c-4.7812 0-8.5781 0.5625-11.391 1.6875z" fill-rule="evenodd"/>
4
+ </svg>
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ <p align="center">
2
+ <img
3
+ class="project-logo"
4
+ src="./NCC-1701-a-blue.svg#gh-light-mode-only"
5
+ alt="WarpDrive"
6
+ width="120px"
7
+ title="WarpDrive" />
8
+ <img
9
+ class="project-logo"
10
+ src="./NCC-1701-a.svg#gh-dark-mode-only"
11
+ alt="WarpDrive"
12
+ width="120px"
13
+ title="WarpDrive" />
14
+ </p>
15
+
16
+ <h3 align="center">Experiments that may or may not make it into the project core</h3>
17
+ <p align="center">Ideal for Having Fun</p>
18
+
19
+ > ⚠️ ***Experimental*** ⚠️
20
+
21
+ ## Installation
22
+
23
+ Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/)
24
+
25
+ ```no-highlight
26
+ pnpm add @warp-drive-mirror/experiments
27
+ ```
28
+
29
+ ## Current Experiments
30
+
31
+ - [PersistedCache](./src/data-worker/README.md)
32
+ - [DocumentStorage](./src/document-storage/README.md)
33
+ - [PersistedCache](./src/persisted-cache/README.md)
@@ -0,0 +1,281 @@
1
+ import { SkipCache } from '@warp-drive-mirror/core-types/request';
2
+ import { macroCondition, getGlobalConfig } from '@embroider/macros';
3
+ class DataWorker {
4
+ constructor(UserStore) {
5
+ this.store = new UserStore();
6
+ this.threads = new Map();
7
+ this.pending = new Map();
8
+ this.initialize();
9
+ }
10
+ initialize() {
11
+ globalThis.onmessage = event => {
12
+ const {
13
+ type
14
+ } = event.data;
15
+ switch (type) {
16
+ case 'connect':
17
+ this.setupThread(event.data.thread, event.ports[0]);
18
+ break;
19
+ }
20
+ };
21
+ }
22
+ setupThread(thread, port) {
23
+ this.threads.set(thread, port);
24
+ this.pending.set(thread, new Map());
25
+ port.onmessage = event => {
26
+ if (event.type === 'close') {
27
+ this.threads.delete(thread);
28
+ return;
29
+ }
30
+ const {
31
+ type
32
+ } = event.data;
33
+ switch (type) {
34
+ case 'abort':
35
+ this.abortRequest(event.data);
36
+ break;
37
+ case 'request':
38
+ void this.request(event.data);
39
+ break;
40
+ }
41
+ };
42
+ }
43
+ abortRequest(event) {
44
+ const {
45
+ thread,
46
+ id
47
+ } = event;
48
+ const future = this.pending.get(thread).get(id);
49
+ if (future) {
50
+ future.abort();
51
+ this.pending.get(thread).delete(id);
52
+ }
53
+ }
54
+ async request(event) {
55
+ const {
56
+ thread,
57
+ id,
58
+ data
59
+ } = event;
60
+ try {
61
+ const future = this.store.request(data);
62
+ this.pending.get(thread).set(id, future);
63
+ const result = await future;
64
+ this.threads.get(thread)?.postMessage({
65
+ type: 'success-response',
66
+ id,
67
+ thread,
68
+ data: prepareResponse(result)
69
+ });
70
+ } catch (error) {
71
+ if (isAbortError(error)) return;
72
+ this.threads.get(thread)?.postMessage({
73
+ type: 'error-response',
74
+ id,
75
+ thread,
76
+ data: error
77
+ });
78
+ } finally {
79
+ this.pending.get(thread).delete(id);
80
+ }
81
+ }
82
+ }
83
+ function softCloneResponse(response) {
84
+ if (!response) return null;
85
+ const clone = {};
86
+ if (response.headers) {
87
+ clone.headers = {};
88
+ for (const [key, value] of response.headers.entries()) {
89
+ clone.headers[key] = value;
90
+ }
91
+ }
92
+ clone.ok = response.ok;
93
+ clone.redirected = response.redirected;
94
+ clone.status = response.status;
95
+ clone.statusText = response.statusText;
96
+ clone.type = response.type;
97
+ clone.url = response.url;
98
+ return clone;
99
+ }
100
+ function isAbortError(error) {
101
+ return error instanceof Error && error.name === 'AbortError';
102
+ }
103
+ function prepareResponse(result) {
104
+ const newResponse = {
105
+ response: softCloneResponse(result.response),
106
+ content: result.content
107
+ };
108
+ return newResponse;
109
+ }
110
+ const MUTATION_OPS = new Set(['createRecord', 'updateRecord', 'deleteRecord']);
111
+
112
+ /**
113
+ * In a Worker, any time we are asked to make a request, data needs to be returned.
114
+ * background requests are ergo no different than foreground requests.
115
+ * @internal
116
+ */
117
+ function calcShouldFetch(store, request, hasCachedValue, identifier) {
118
+ const {
119
+ cacheOptions
120
+ } = request;
121
+ return request.op && MUTATION_OPS.has(request.op) || cacheOptions?.reload || cacheOptions?.backgroundReload || !hasCachedValue || (store.lifetimes && identifier ? store.lifetimes.isHardExpired(identifier, store) || store.lifetimes.isSoftExpired(identifier, store) : false);
122
+ }
123
+ function isMutation(request) {
124
+ return Boolean(request.op && MUTATION_OPS.has(request.op));
125
+ }
126
+ function isCacheAffecting(document) {
127
+ if (!isMutation(document.request)) {
128
+ return true;
129
+ }
130
+ // a mutation combined with a 204 has no cache impact when no known records were involved
131
+ // a createRecord with a 201 with an empty response and no known records should similarly
132
+ // have no cache impact
133
+
134
+ if (document.request.op === 'createRecord' && document.response?.status === 201) {
135
+ return document.content ? Object.keys(document.content).length > 0 : false;
136
+ }
137
+ return document.response?.status !== 204;
138
+ }
139
+ function isAggregateError(error) {
140
+ return error instanceof AggregateError || error.name === 'AggregateError' && Array.isArray(error.errors);
141
+ }
142
+ // TODO @runspired, consider if we should deep freeze errors (potentially only in debug) vs cloning them
143
+ function cloneError(error) {
144
+ const isAggregate = isAggregateError(error);
145
+ const cloned = isAggregate ? new AggregateError(structuredClone(error.errors), error.message) : new Error(error.message);
146
+ cloned.stack = error.stack;
147
+ cloned.error = error.error;
148
+
149
+ // copy over enumerable properties
150
+ Object.assign(cloned, error);
151
+ return cloned;
152
+ }
153
+ const CacheHandler = {
154
+ request(context, next) {
155
+ // if we have no cache or no cache-key skip cache handling
156
+ if (!context.request.store || context.request.cacheOptions?.[SkipCache]) {
157
+ return next(context.request);
158
+ }
159
+ const {
160
+ store
161
+ } = context.request;
162
+ const identifier = store.identifierCache.getOrCreateDocumentIdentifier(context.request);
163
+ const peeked = identifier ? store.cache.peekRequest(identifier) : null;
164
+
165
+ // In a Worker, any time we are asked to make a request, data needs to be returned.
166
+ // background requests are ergo no different than foreground requests.
167
+ if (calcShouldFetch(store, context.request, !!peeked, identifier)) {
168
+ return fetchContentAndHydrate(next, context, identifier);
169
+ }
170
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
171
+ if (!test) {
172
+ throw new Error(`Expected a peeked request to be present`);
173
+ }
174
+ })(peeked) : {};
175
+ context.setResponse(peeked.response);
176
+ if ('error' in peeked) {
177
+ throw peeked;
178
+ }
179
+ return maybeUpdateObjects(store, peeked.content);
180
+ }
181
+ };
182
+ function maybeUpdateObjects(store, document) {
183
+ if (!document) {
184
+ return document;
185
+ }
186
+ if (Array.isArray(document.data)) {
187
+ const data = document.data.map(identifier => {
188
+ return store.cache.peek(identifier);
189
+ });
190
+ return Object.assign({}, document, {
191
+ data
192
+ });
193
+ } else {
194
+ const data = document.data ? store.cache.peek(document.data) : null;
195
+ return Object.assign({}, document, {
196
+ data
197
+ });
198
+ }
199
+ }
200
+ function updateCacheForSuccess(store, request, document) {
201
+ let response = null;
202
+ if (isMutation(request)) {
203
+ const record = request.data?.record || request.records?.[0];
204
+ if (record) {
205
+ response = store.cache.didCommit(record, document);
206
+
207
+ // a mutation combined with a 204 has no cache impact when no known records were involved
208
+ // a createRecord with a 201 with an empty response and no known records should similarly
209
+ // have no cache impact
210
+ } else if (isCacheAffecting(document)) {
211
+ response = store.cache.put(document);
212
+ }
213
+ } else {
214
+ response = store.cache.put(document);
215
+ }
216
+ return maybeUpdateObjects(store, response);
217
+ }
218
+ function handleFetchSuccess(store, request, identifier, document) {
219
+ let response;
220
+ store._join(() => {
221
+ response = updateCacheForSuccess(store, request, document);
222
+ });
223
+ if (store.lifetimes?.didRequest) {
224
+ store.lifetimes.didRequest(request, document.response, identifier, store);
225
+ }
226
+ return response;
227
+ }
228
+ function updateCacheForError(store, request, error) {
229
+ if (isMutation(request)) {
230
+ // TODO similar to didCommit we should spec this to be similar to cache.put for handling full response
231
+ // currently we let the response remain undefiend.
232
+ const errors = error && error.content && typeof error.content === 'object' && 'errors' in error.content && Array.isArray(error.content.errors) ? error.content.errors : undefined;
233
+ const record = request.data?.record || request.records?.[0];
234
+ store.cache.commitWasRejected(record, errors);
235
+ } else {
236
+ return store.cache.put(error);
237
+ }
238
+ }
239
+ function handleFetchError(store, request, identifier, error) {
240
+ if (request.signal?.aborted) {
241
+ throw error;
242
+ }
243
+ let response;
244
+ store._join(() => {
245
+ response = updateCacheForError(store, request, error);
246
+ });
247
+ if (identifier && store.lifetimes?.didRequest) {
248
+ store.lifetimes.didRequest(request, error.response, identifier, store);
249
+ }
250
+ if (isMutation(request)) {
251
+ throw error;
252
+ }
253
+ const newError = cloneError(error);
254
+ newError.content = response;
255
+ throw newError;
256
+ }
257
+ function fetchContentAndHydrate(next, context, identifier) {
258
+ const {
259
+ request
260
+ } = context;
261
+ const {
262
+ store
263
+ } = context.request;
264
+ if (isMutation(request)) {
265
+ // TODO should we handle multiple records in request.records by iteratively calling willCommit for each
266
+ const record = request.data?.record || request.records?.[0];
267
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
268
+ if (!test) {
269
+ throw new Error(`Expected to receive a list of records included in the ${request.op} request`);
270
+ }
271
+ })(record) : {};
272
+ if (record) {
273
+ store.cache.willCommit(record, context);
274
+ }
275
+ }
276
+ if (store.lifetimes?.willRequest) {
277
+ store.lifetimes.willRequest(request, identifier, store);
278
+ }
279
+ return next(request).then(document => handleFetchSuccess(store, request, identifier, document), error => handleFetchError(store, request, identifier, error));
280
+ }
281
+ export { CacheHandler, DataWorker };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-worker.js","sources":["../src/data-worker/worker.ts","../src/data-worker/utils.ts","../src/data-worker/cache-handler.ts"],"sourcesContent":["import type { Future, ResponseInfo, StructuredDataDocument } from '@ember-data-mirror/request';\nimport type Store from '@ember-data-mirror/store';\n\nimport type { AbortEventData, RequestEventData, ThreadInitEventData, WorkerThreadEvent } from './types';\n\nexport class DataWorker {\n declare store: Store;\n declare threads: Map<string, MessagePort>;\n declare pending: Map<string, Map<number, Future<unknown>>>;\n\n constructor(UserStore: typeof Store) {\n this.store = new UserStore();\n this.threads = new Map();\n this.pending = new Map();\n this.initialize();\n }\n\n initialize() {\n globalThis.onmessage = (event: MessageEvent<ThreadInitEventData>) => {\n const { type } = event.data;\n\n switch (type) {\n case 'connect':\n this.setupThread(event.data.thread, event.ports[0]);\n break;\n }\n };\n }\n\n setupThread(thread: string, port: MessagePort) {\n this.threads.set(thread, port);\n this.pending.set(thread, new Map());\n port.onmessage = (event: WorkerThreadEvent) => {\n if (event.type === 'close') {\n this.threads.delete(thread);\n return;\n }\n\n const { type } = event.data;\n switch (type) {\n case 'abort':\n this.abortRequest(event.data);\n break;\n case 'request':\n void this.request(event.data);\n break;\n }\n };\n }\n\n abortRequest(event: AbortEventData) {\n const { thread, id } = event;\n const future = this.pending.get(thread)!.get(id);\n\n if (future) {\n future.abort();\n this.pending.get(thread)!.delete(id);\n }\n }\n\n async request(event: RequestEventData) {\n const { thread, id, data } = event;\n\n try {\n const future = this.store.request(data);\n this.pending.get(thread)!.set(id, future);\n\n const result = await future;\n\n this.threads.get(thread)?.postMessage({ type: 'success-response', id, thread, data: prepareResponse(result) });\n } catch (error) {\n if (isAbortError(error)) return;\n\n this.threads.get(thread)?.postMessage({ type: 'error-response', id, thread, data: error });\n } finally {\n this.pending.get(thread)!.delete(id);\n }\n }\n}\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] };\n\nfunction softCloneResponse(response: Response | ResponseInfo | null) {\n if (!response) return null;\n\n const clone: Partial<Mutable<Omit<Response, 'headers'>>> & { headers?: Record<string, string | number> } = {};\n\n if (response.headers) {\n clone.headers = {};\n for (const [key, value] of response.headers.entries()) {\n clone.headers[key] = value;\n }\n }\n\n clone.ok = response.ok;\n clone.redirected = response.redirected;\n clone.status = response.status;\n clone.statusText = response.statusText;\n clone.type = response.type;\n clone.url = response.url;\n\n return clone;\n}\n\nfunction isAbortError(error: unknown): error is Error {\n return error instanceof Error && error.name === 'AbortError';\n}\n\nfunction prepareResponse<T>(result: StructuredDataDocument<T>) {\n const newResponse = {\n response: softCloneResponse(result.response),\n content: result.content,\n };\n\n return newResponse;\n}\n","import type Store from '@ember-data-mirror/store';\nimport type { StableDocumentIdentifier } from '@warp-drive-mirror/core-types/identifier';\nimport type {\n ImmutableCreateRequestOptions,\n ImmutableDeleteRequestOptions,\n ImmutableRequestInfo,\n ImmutableUpdateRequestOptions,\n StructuredDataDocument,\n} from '@warp-drive-mirror/core-types/request';\nimport type { ApiError } from '@warp-drive-mirror/core-types/spec/error';\n\nexport const MUTATION_OPS = new Set(['createRecord', 'updateRecord', 'deleteRecord']);\n\n/**\n * In a Worker, any time we are asked to make a request, data needs to be returned.\n * background requests are ergo no different than foreground requests.\n * @internal\n */\nexport function calcShouldFetch(\n store: Store,\n request: ImmutableRequestInfo,\n hasCachedValue: boolean,\n identifier: StableDocumentIdentifier | null\n): boolean {\n const { cacheOptions } = request;\n return (\n (request.op && MUTATION_OPS.has(request.op)) ||\n cacheOptions?.reload ||\n cacheOptions?.backgroundReload ||\n !hasCachedValue ||\n (store.lifetimes && identifier\n ? store.lifetimes.isHardExpired(identifier, store) || store.lifetimes.isSoftExpired(identifier, store)\n : false)\n );\n}\n\nexport function isMutation(\n request: Partial<ImmutableRequestInfo>\n): request is ImmutableUpdateRequestOptions | ImmutableCreateRequestOptions | ImmutableDeleteRequestOptions {\n return Boolean(request.op && MUTATION_OPS.has(request.op));\n}\n\nexport function isCacheAffecting<T>(document: StructuredDataDocument<T>): boolean {\n if (!isMutation(document.request)) {\n return true;\n }\n // a mutation combined with a 204 has no cache impact when no known records were involved\n // a createRecord with a 201 with an empty response and no known records should similarly\n // have no cache impact\n\n if (document.request.op === 'createRecord' && document.response?.status === 201) {\n return document.content ? Object.keys(document.content).length > 0 : false;\n }\n\n return document.response?.status !== 204;\n}\n\nfunction isAggregateError(error: Error & { errors?: ApiError[] }): error is AggregateError & { errors: ApiError[] } {\n return error instanceof AggregateError || (error.name === 'AggregateError' && Array.isArray(error.errors));\n}\n\ntype RobustError = Error & { error: string | object; errors?: ApiError[]; content?: unknown };\n\n// TODO @runspired, consider if we should deep freeze errors (potentially only in debug) vs cloning them\nexport function cloneError(error: RobustError) {\n const isAggregate = isAggregateError(error);\n\n const cloned = (\n isAggregate ? new AggregateError(structuredClone(error.errors), error.message) : new Error(error.message)\n ) as RobustError;\n cloned.stack = error.stack!;\n cloned.error = error.error;\n\n // copy over enumerable properties\n Object.assign(cloned, error);\n\n return cloned;\n}\n","import type { CacheHandler as CacheHandlerType, Future, NextFn } from '@ember-data-mirror/request';\nimport type Store from '@ember-data-mirror/store';\nimport type { StoreRequestContext } from '@ember-data-mirror/store';\nimport { assert } from '@warp-drive-mirror/build-config/macros';\nimport type { StableDocumentIdentifier } from '@warp-drive-mirror/core-types/identifier';\nimport type { StructuredDataDocument, StructuredErrorDocument } from '@warp-drive-mirror/core-types/request';\nimport { SkipCache } from '@warp-drive-mirror/core-types/request';\nimport type { ResourceDataDocument, ResourceErrorDocument } from '@warp-drive-mirror/core-types/spec/document';\nimport type { ApiError } from '@warp-drive-mirror/core-types/spec/error';\n\nimport { calcShouldFetch, cloneError, isCacheAffecting, isMutation } from './utils';\n\n/**\n * A simplified CacheHandler that hydrates ResourceDataDocuments from the cache\n * with their referenced resources.\n *\n * @typedoc\n */\nexport const CacheHandler: CacheHandlerType = {\n request<T>(context: StoreRequestContext, next: NextFn<T>): Promise<T | StructuredDataDocument<T>> | Future<T> | T {\n // if we have no cache or no cache-key skip cache handling\n if (!context.request.store || context.request.cacheOptions?.[SkipCache]) {\n return next(context.request);\n }\n\n const { store } = context.request;\n const identifier = store.identifierCache.getOrCreateDocumentIdentifier(context.request);\n const peeked = identifier ? store.cache.peekRequest(identifier) : null;\n\n // In a Worker, any time we are asked to make a request, data needs to be returned.\n // background requests are ergo no different than foreground requests.\n if (calcShouldFetch(store, context.request, !!peeked, identifier)) {\n return fetchContentAndHydrate(next, context, identifier);\n }\n\n assert(`Expected a peeked request to be present`, peeked);\n context.setResponse(peeked.response);\n\n if ('error' in peeked) {\n throw peeked;\n }\n\n return maybeUpdateObjects<T>(store, peeked.content as ResourceDataDocument);\n },\n};\n\nfunction maybeUpdateObjects<T>(store: Store, document: ResourceDataDocument | null): T {\n if (!document) {\n return document as T;\n }\n\n if (Array.isArray(document.data)) {\n const data = document.data.map((identifier) => {\n return store.cache.peek(identifier);\n });\n\n return Object.assign({}, document, { data }) as T;\n } else {\n const data = (document.data ? store.cache.peek(document.data) : null) as T;\n return Object.assign({}, document, { data }) as T;\n }\n}\n\nfunction updateCacheForSuccess<T>(\n store: Store,\n request: StoreRequestContext['request'],\n document: StructuredDataDocument<T>\n) {\n let response: ResourceDataDocument | null = null;\n if (isMutation(request)) {\n const record = request.data?.record || request.records?.[0];\n if (record) {\n response = store.cache.didCommit(record, document) as ResourceDataDocument;\n\n // a mutation combined with a 204 has no cache impact when no known records were involved\n // a createRecord with a 201 with an empty response and no known records should similarly\n // have no cache impact\n } else if (isCacheAffecting(document)) {\n response = store.cache.put(document) as ResourceDataDocument;\n }\n } else {\n response = store.cache.put(document) as ResourceDataDocument;\n }\n return maybeUpdateObjects(store, response);\n}\n\nfunction handleFetchSuccess<T>(\n store: Store,\n request: StoreRequestContext['request'],\n identifier: StableDocumentIdentifier | null,\n document: StructuredDataDocument<T>\n): T {\n let response: ResourceDataDocument;\n store._join(() => {\n response = updateCacheForSuccess<T>(store, request, document) as ResourceDataDocument;\n });\n\n if (store.lifetimes?.didRequest) {\n store.lifetimes.didRequest(request, document.response, identifier, store);\n }\n\n return response! as T;\n}\n\nfunction updateCacheForError<T>(\n store: Store,\n request: StoreRequestContext['request'],\n error: StructuredErrorDocument<T>\n) {\n if (isMutation(request)) {\n // TODO similar to didCommit we should spec this to be similar to cache.put for handling full response\n // currently we let the response remain undefiend.\n const errors =\n error &&\n error.content &&\n typeof error.content === 'object' &&\n 'errors' in error.content &&\n Array.isArray(error.content.errors)\n ? (error.content.errors as ApiError[])\n : undefined;\n\n const record = request.data?.record || request.records?.[0];\n\n store.cache.commitWasRejected(record, errors);\n } else {\n return store.cache.put(error) as ResourceErrorDocument;\n }\n}\n\nfunction handleFetchError<T>(\n store: Store,\n request: StoreRequestContext['request'],\n identifier: StableDocumentIdentifier | null,\n error: StructuredErrorDocument<T>\n): never {\n if (request.signal?.aborted) {\n throw error;\n }\n let response: ResourceErrorDocument | undefined;\n store._join(() => {\n response = updateCacheForError(store, request, error);\n });\n\n if (identifier && store.lifetimes?.didRequest) {\n store.lifetimes.didRequest(request, error.response, identifier, store);\n }\n\n if (isMutation(request)) {\n throw error;\n }\n\n const newError = cloneError(error);\n newError.content = response!;\n throw newError;\n}\n\nfunction fetchContentAndHydrate<T>(\n next: NextFn<T>,\n context: StoreRequestContext,\n identifier: StableDocumentIdentifier | null\n): Promise<T> {\n const { request } = context;\n const { store } = context.request;\n\n if (isMutation(request)) {\n // TODO should we handle multiple records in request.records by iteratively calling willCommit for each\n const record = request.data?.record || request.records?.[0];\n assert(`Expected to receive a list of records included in the ${request.op} request`, record);\n if (record) {\n store.cache.willCommit(record, context);\n }\n }\n\n if (store.lifetimes?.willRequest) {\n store.lifetimes.willRequest(request, identifier, store);\n }\n\n return next(request).then(\n (document) => handleFetchSuccess(store, request, identifier, document),\n (error: StructuredErrorDocument<T>) => handleFetchError(store, request, identifier, error)\n );\n}\n"],"names":["DataWorker","constructor","UserStore","store","threads","Map","pending","initialize","globalThis","onmessage","event","type","data","setupThread","thread","ports","port","set","delete","abortRequest","request","id","future","get","abort","result","postMessage","prepareResponse","error","isAbortError","softCloneResponse","response","clone","headers","key","value","entries","ok","redirected","status","statusText","url","Error","name","newResponse","content","MUTATION_OPS","Set","calcShouldFetch","hasCachedValue","identifier","cacheOptions","op","has","reload","backgroundReload","lifetimes","isHardExpired","isSoftExpired","isMutation","Boolean","isCacheAffecting","document","Object","keys","length","isAggregateError","AggregateError","Array","isArray","errors","cloneError","isAggregate","cloned","structuredClone","message","stack","assign","CacheHandler","context","next","SkipCache","identifierCache","getOrCreateDocumentIdentifier","peeked","cache","peekRequest","fetchContentAndHydrate","macroCondition","getGlobalConfig","WarpDrive","env","DEBUG","test","setResponse","maybeUpdateObjects","map","peek","updateCacheForSuccess","record","records","didCommit","put","handleFetchSuccess","_join","didRequest","updateCacheForError","undefined","commitWasRejected","handleFetchError","signal","aborted","newError","willCommit","willRequest","then"],"mappings":"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"}
@@ -0,0 +1,243 @@
1
+ const WARP_DRIVE_STORAGE_FILE_NAME = 'warp-drive_document-storage';
2
+ const WARP_DRIVE_STORAGE_VERSION = 1;
3
+
4
+ /**
5
+ * DocumentStorage is specifically designed around WarpDrive Cache and Request concepts.
6
+ *
7
+ * CacheFileDocument is a StructuredDocument (request response) whose `content` is
8
+ * the ResourceDocument returned by inserting the request into a Store's Cache.
9
+ */
10
+
11
+ /**
12
+ * A CacheDocument is a reconstructed request response that rehydrates ResourceDocument
13
+ * with the associated resources based on their identifiers.
14
+ */
15
+
16
+ class InternalDocumentStorage {
17
+ constructor(options) {
18
+ this.options = options;
19
+ this._lastModified = 0;
20
+ this._invalidated = true;
21
+ this._fileHandle = this._open(options.scope);
22
+ this._channel = Object.assign(new BroadcastChannel(options.scope), {
23
+ onmessage: this._onMessage.bind(this)
24
+ });
25
+ }
26
+ _onMessage(_event) {
27
+ this._invalidated = true;
28
+ }
29
+ async _open(scope) {
30
+ const directoryHandle = await navigator.storage.getDirectory();
31
+ const fileHandle = await directoryHandle.getFileHandle(scope, {
32
+ create: true
33
+ });
34
+ return fileHandle;
35
+ }
36
+ async _read() {
37
+ if (this._filePromise) {
38
+ return this._filePromise;
39
+ }
40
+ if (this._invalidated) {
41
+ const updateFile = async () => {
42
+ const fileHandle = await this._fileHandle;
43
+ const file = await fileHandle.getFile();
44
+ const lastModified = file.lastModified;
45
+ if (lastModified === this._lastModified && this._cache) {
46
+ return this._cache;
47
+ }
48
+ const contents = await file.text();
49
+ const cache = contents ? JSON.parse(contents) : {
50
+ documents: [],
51
+ resources: []
52
+ };
53
+ const documents = new Map(cache.documents);
54
+ const resources = new Map(cache.resources);
55
+ const cacheMap = {
56
+ documents,
57
+ resources
58
+ };
59
+ this._cache = cacheMap;
60
+ this._invalidated = false;
61
+ this._lastModified = lastModified;
62
+ return cacheMap;
63
+ };
64
+ this._filePromise = updateFile();
65
+ await this._filePromise;
66
+ this._filePromise = null;
67
+ }
68
+ return this._cache;
69
+ }
70
+ async _patch(documentKey, document, updatedResources) {
71
+ const fileHandle = await this._fileHandle;
72
+ // secure a lock before getting latest state
73
+ const writable = await fileHandle.createWritable();
74
+ const cache = await this._read();
75
+ cache.documents.set(documentKey, document);
76
+ updatedResources.forEach((resource, key) => {
77
+ cache.resources.set(key, resource);
78
+ });
79
+ const documents = [...cache.documents.entries()];
80
+ const resources = [...cache.resources.entries()];
81
+ const cacheFile = {
82
+ documents,
83
+ resources
84
+ };
85
+ await writable.write(JSON.stringify(cacheFile));
86
+ await writable.close();
87
+ this._channel.postMessage({
88
+ type: 'patch',
89
+ key: documentKey,
90
+ resources: [...updatedResources.keys()]
91
+ });
92
+ }
93
+ async getDocument(key) {
94
+ const cache = await this._read();
95
+ // clone the document to avoid leaking the internal cache
96
+ const document = structuredClone(cache.documents.get(key.lid));
97
+ if (!document) {
98
+ return null;
99
+ }
100
+
101
+ // expand the document with the resources
102
+ if (document.content) {
103
+ if (docHasData(document.content)) {
104
+ let data = null;
105
+ if (Array.isArray(document.content.data)) {
106
+ data = document.content.data.map(resourceIdentifier => {
107
+ const resource = cache.resources.get(resourceIdentifier.lid);
108
+ if (!resource) {
109
+ throw new Error(`Resource not found for ${resourceIdentifier.lid}`);
110
+ }
111
+
112
+ // clone the resource to avoid leaking the internal cache
113
+ return structuredClone(resource);
114
+ });
115
+ } else if (document.content.data) {
116
+ const resource = cache.resources.get(document.content.data.lid);
117
+ if (!resource) {
118
+ throw new Error(`Resource not found for ${document.content.data.lid}`);
119
+ }
120
+
121
+ // clone the resource to avoid leaking the internal cache
122
+ data = structuredClone(resource);
123
+ }
124
+ if (document.content.included) {
125
+ const included = document.content.included.map(resourceIdentifier => {
126
+ const resource = cache.resources.get(resourceIdentifier.lid);
127
+ if (!resource) {
128
+ throw new Error(`Resource not found for ${resourceIdentifier.lid}`);
129
+ }
130
+
131
+ // clone the resource to avoid leaking the internal cache
132
+ return structuredClone(resource);
133
+ });
134
+ document.content.included = included;
135
+ }
136
+ document.content.data = data;
137
+ }
138
+ }
139
+ return document;
140
+ }
141
+ async putDocument(document, resourceCollector) {
142
+ const resources = new Map();
143
+ if (!document.content) {
144
+ throw new Error(`Document content is missing, only finalized documents can be stored`);
145
+ }
146
+ if (!document.content.lid) {
147
+ throw new Error(`Document content is missing a lid, only documents with a cache-key can be stored`);
148
+ }
149
+ if (docHasData(document.content)) {
150
+ if (Array.isArray(document.content.data)) {
151
+ document.content.data.forEach(resourceIdentifier => {
152
+ const resource = resourceCollector(resourceIdentifier);
153
+ resources.set(resourceIdentifier.lid, structuredClone(resource));
154
+ });
155
+ } else if (document.content.data) {
156
+ const resource = resourceCollector(document.content.data);
157
+ resources.set(document.content.data.lid, structuredClone(resource));
158
+ }
159
+ if (document.content.included) {
160
+ document.content.included.forEach(resourceIdentifier => {
161
+ const resource = resourceCollector(resourceIdentifier);
162
+ resources.set(resourceIdentifier.lid, structuredClone(resource));
163
+ });
164
+ }
165
+ }
166
+ await this._patch(document.content.lid, structuredClone(document), resources);
167
+ }
168
+ async clear(reset) {
169
+ const fileHandle = await this._fileHandle;
170
+ const writable = await fileHandle.createWritable();
171
+ await writable.write('');
172
+ await writable.close();
173
+ this._invalidated = true;
174
+ this._lastModified = 0;
175
+ this._cache = null;
176
+ this._filePromise = null;
177
+ this._channel.postMessage({
178
+ type: 'clear'
179
+ });
180
+ if (!reset) {
181
+ this._channel.close();
182
+ this._channel = null;
183
+ if (!this.options.isolated) {
184
+ Storages.delete(this.options.scope);
185
+ }
186
+ }
187
+ }
188
+ }
189
+ function docHasData(doc) {
190
+ return 'data' in doc;
191
+ }
192
+ const Storages = new Map();
193
+
194
+ /**
195
+ * DocumentStorage is a wrapper around the StorageManager API that provides
196
+ * a simple interface for reading and updating documents and requests.
197
+ *
198
+ * Some goals for this experiment:
199
+ *
200
+ * - optimize for storing requests/documents
201
+ * - optimize for storing resources
202
+ * - optimize for looking up resources associated to a document
203
+ * - optimize for notifying cross-tab when data is updated
204
+ *
205
+ * optional features:
206
+ *
207
+ * - support for offline mode
208
+ * - ?? support for relationship based cache traversal
209
+ * - a way to index records by type + another field (e.g updatedAt/createAt/name)
210
+ * such that simple queries can be done without having to scan all records
211
+ */
212
+ class DocumentStorage {
213
+ constructor(options = {}) {
214
+ options.isolated = options.isolated ?? false;
215
+ options.scope = options.scope ?? 'default';
216
+ const fileName = `${WARP_DRIVE_STORAGE_FILE_NAME}@version_${WARP_DRIVE_STORAGE_VERSION}:${options.scope}`;
217
+ if (!options.isolated && Storages.has(fileName)) {
218
+ const storage = Storages.get(fileName);
219
+ if (storage) {
220
+ this._storage = storage.deref();
221
+ return;
222
+ }
223
+ }
224
+ const storage = new InternalDocumentStorage({
225
+ scope: fileName,
226
+ isolated: options.isolated
227
+ });
228
+ this._storage = storage;
229
+ if (!options.isolated) {
230
+ Storages.set(fileName, new WeakRef(storage));
231
+ }
232
+ }
233
+ getDocument(key) {
234
+ return this._storage.getDocument(key);
235
+ }
236
+ putDocument(document, resourceCollector) {
237
+ return this._storage.putDocument(document, resourceCollector);
238
+ }
239
+ clear(reset) {
240
+ return this._storage.clear(reset);
241
+ }
242
+ }
243
+ export { DocumentStorage };