sliftutils 1.1.4 → 1.1.41

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 (55) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.cursor/rules/api-calls.mdc +16 -0
  3. package/.cursor/rules/coding-styles.mdc +50 -0
  4. package/.cursor/rules/components.mdc +44 -0
  5. package/.cursor/rules/disk-collection.mdc +31 -0
  6. package/.cursor/rules/general-guidelines.mdc +11 -0
  7. package/.cursor/rules/mobx-state.mdc +33 -0
  8. package/.cursor/rules/styling-css.mdc +99 -0
  9. package/CLAUDE.md +211 -0
  10. package/builders/hotReload.ts +23 -20
  11. package/builders/setup.ts +2 -2
  12. package/dist/test.ts.cache +13 -0
  13. package/index.d.ts +167 -14
  14. package/misc/apiKeys.d.ts +1 -0
  15. package/misc/apiKeys.tsx +7 -3
  16. package/misc/dist/apiKeys.tsx.cache +145 -0
  17. package/misc/dist/openrouter.ts.cache +119 -0
  18. package/misc/dist/yaml.ts.cache +45 -0
  19. package/misc/dist/yamlBase.ts.cache +2406 -0
  20. package/misc/getSecret.d.ts +1 -0
  21. package/misc/getSecret.ts +7 -0
  22. package/misc/https/httpsCerts.d.ts +17 -0
  23. package/misc/https/httpsCerts.ts +4 -4
  24. package/misc/openrouter.d.ts +1 -0
  25. package/misc/openrouter.ts +32 -4
  26. package/misc/zip.d.ts +2 -12
  27. package/misc/zip.ts +2 -97
  28. package/package.json +4 -3
  29. package/render-utils/InputLabel.d.ts +1 -2
  30. package/render-utils/InputLabel.tsx +1 -1
  31. package/render-utils/autoMeasure.d.ts +1 -0
  32. package/render-utils/autoMeasure.ts +43 -0
  33. package/render-utils/dist/Input.tsx.cache +319 -0
  34. package/render-utils/dist/InputLabel.tsx.cache +220 -0
  35. package/render-utils/dist/modal.tsx.cache +69 -0
  36. package/render-utils/dist/observer.tsx.cache +6 -3
  37. package/render-utils/modal.tsx +1 -1
  38. package/storage/DiskCollection.d.ts +17 -0
  39. package/storage/DiskCollection.ts +57 -5
  40. package/storage/FileFolderAPI.d.ts +3 -0
  41. package/storage/FileFolderAPI.tsx +104 -36
  42. package/storage/IStorage.d.ts +4 -0
  43. package/storage/IStorage.ts +3 -0
  44. package/storage/IndexedDBFileFolderAPI.ts +6 -0
  45. package/storage/PrivateFileSystemStorage.d.ts +4 -0
  46. package/storage/PrivateFileSystemStorage.ts +11 -0
  47. package/storage/StorageObservable.d.ts +4 -0
  48. package/storage/StorageObservable.ts +27 -2
  49. package/storage/StorageObservableAsync.d.ts +2 -0
  50. package/storage/StorageObservableAsync.ts +20 -0
  51. package/storage/backblaze.d.ts +97 -0
  52. package/storage/backblaze.ts +915 -0
  53. package/test.ts +10 -0
  54. package/yarn.lock +139 -4
  55. package/.cursorrules +0 -251
package/test.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { yamlOpenRouterCall } from "./misc/openrouter";
2
+
3
+ async function main() {
4
+ let test = await yamlOpenRouterCall({
5
+ model: "google/gemini-2.5-flash",
6
+ messages: [{ role: "user", content: "" }],
7
+ });
8
+ console.log(test);
9
+ }
10
+ main().catch(console.error).finally(() => process.exit(0));
package/yarn.lock CHANGED
@@ -79,6 +79,11 @@
79
79
  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2"
80
80
  integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==
81
81
 
82
+ "@harperfast/extended-iterable@^1.0.3":
83
+ version "1.0.3"
84
+ resolved "https://registry.yarnpkg.com/@harperfast/extended-iterable/-/extended-iterable-1.0.3.tgz#471489c5058331017e821bf6c33de70fc2c073ee"
85
+ integrity sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw==
86
+
82
87
  "@humanwhocodes/config-array@^0.13.0":
83
88
  version "0.13.0"
84
89
  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748"
@@ -98,6 +103,71 @@
98
103
  resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3"
99
104
  integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==
100
105
 
106
+ "@lmdb/lmdb-darwin-arm64@3.5.4":
107
+ version "3.5.4"
108
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.5.4.tgz#ff51012dff6af26771f71abaa739b0f71d0018d8"
109
+ integrity sha512-Kk4Kz3iyu1QiLsLZBS9Af1eSKUC8VR2T+/jyE2iAyuGw2VwK08pp5iTbZnXn6sWu0LogO/RFktMxOjiDA2sS3w==
110
+
111
+ "@lmdb/lmdb-darwin-x64@3.5.4":
112
+ version "3.5.4"
113
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.5.4.tgz#1f8f1f571e07367ce3974ff50ae81719e5c8cfd6"
114
+ integrity sha512-BEe5Rp3trn26oxoXOVL5HVDoiYmjUDwr8NRPkBOdUdCSBEorKI+7JrZLRKAdxO+G6cGQLgseXk0gR7qIQa7aGw==
115
+
116
+ "@lmdb/lmdb-linux-arm64@3.5.4":
117
+ version "3.5.4"
118
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.5.4.tgz#88c345e5061084c29446f5778ccef5d499a5c42c"
119
+ integrity sha512-cUXEengO8o60v1SWerJTH4/RH4U3+9jC0/4njp2Z9NdmvaGzhKsbRM2wpXuRYrN8tytsoJCg0SvWEWwHAwLbCA==
120
+
121
+ "@lmdb/lmdb-linux-arm@3.5.4":
122
+ version "3.5.4"
123
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.5.4.tgz#a4ddcf697642d0d72b0c3a1eea7550bfdeb071c5"
124
+ integrity sha512-SGbFR7816uBcTHc2ZY4S6WyOkl9bICnzqTQd2Mv4V/j24cfds88xx2nC6cm/y8zGQL7Ds31YF/5NGxjgcdM5Hw==
125
+
126
+ "@lmdb/lmdb-linux-x64@3.5.4":
127
+ version "3.5.4"
128
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.5.4.tgz#72b3805f7f027f9df9a3af6a1b1fc30c858d486e"
129
+ integrity sha512-Gxq8jpgOWXwd0PUR+c9R2Ik1/uBnGd5GMIIzRRDqABCkvmjtC3KWcyhesV9jSPCz759isl0NlbsstZ2oyvk8lA==
130
+
131
+ "@lmdb/lmdb-win32-arm64@3.5.4":
132
+ version "3.5.4"
133
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.5.4.tgz#a23f1457106835c2270b3b05379f199aaa466bc9"
134
+ integrity sha512-pKv1DJ1bPZAaHkdFsSz5IDfUG8x9vntgquXF9/Dm2xuupcIe/EkLzylpoBxppFVK5vzbV561Dq26jNY2fIMA7g==
135
+
136
+ "@lmdb/lmdb-win32-x64@3.5.4":
137
+ version "3.5.4"
138
+ resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.4.tgz#d52c5e00bbc013d056059a09780e549ee015eb0f"
139
+ integrity sha512-JF1BmLCm9kGEVZgYmJq43zeQVdHVgAJnTi/NURWEsy6L1ZrrlSmdltS+D17QN4LODwf+1LMXAA9auIZVXtWwzw==
140
+
141
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3":
142
+ version "3.0.3"
143
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz#9edec61b22c3082018a79f6d1c30289ddf3d9d11"
144
+ integrity sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==
145
+
146
+ "@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3":
147
+ version "3.0.3"
148
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz#33677a275204898ad8acbf62734fc4dc0b6a4855"
149
+ integrity sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==
150
+
151
+ "@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3":
152
+ version "3.0.3"
153
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz#19edf7cdc2e7063ee328403c1d895a86dd28f4bb"
154
+ integrity sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==
155
+
156
+ "@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3":
157
+ version "3.0.3"
158
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz#94fb0543ba2e28766c3fc439cabbe0440ae70159"
159
+ integrity sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==
160
+
161
+ "@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3":
162
+ version "3.0.3"
163
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz#4a0609ab5fe44d07c9c60a11e4484d3c38bbd6e3"
164
+ integrity sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==
165
+
166
+ "@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3":
167
+ version "3.0.3"
168
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz#0aa5502d547b57abfc4ac492de68e2006e417242"
169
+ integrity sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==
170
+
101
171
  "@nodelib/fs.scandir@2.1.5":
102
172
  version "2.1.5"
103
173
  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -1410,6 +1480,26 @@ levn@^0.4.1:
1410
1480
  prelude-ls "^1.2.1"
1411
1481
  type-check "~0.4.0"
1412
1482
 
1483
+ lmdb@^3.5.1:
1484
+ version "3.5.4"
1485
+ resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-3.5.4.tgz#c12942aacbd2d5b0b1b28adac1500c37984ce458"
1486
+ integrity sha512-9FKQA6G1MMtqNxfxvSBNXD/axeG2QRjYbNh0/ykRL5xYcRbCm2vXq7B9bhc7nSuKdHzr8/BHIwfPuYYH1UsXXw==
1487
+ dependencies:
1488
+ "@harperfast/extended-iterable" "^1.0.3"
1489
+ msgpackr "^1.11.2"
1490
+ node-addon-api "^6.1.0"
1491
+ node-gyp-build-optional-packages "5.2.2"
1492
+ ordered-binary "^1.5.3"
1493
+ weak-lru-cache "^1.2.2"
1494
+ optionalDependencies:
1495
+ "@lmdb/lmdb-darwin-arm64" "3.5.4"
1496
+ "@lmdb/lmdb-darwin-x64" "3.5.4"
1497
+ "@lmdb/lmdb-linux-arm" "3.5.4"
1498
+ "@lmdb/lmdb-linux-arm64" "3.5.4"
1499
+ "@lmdb/lmdb-linux-x64" "3.5.4"
1500
+ "@lmdb/lmdb-win32-arm64" "3.5.4"
1501
+ "@lmdb/lmdb-win32-x64" "3.5.4"
1502
+
1413
1503
  locate-path@^5.0.0:
1414
1504
  version "5.0.0"
1415
1505
  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@@ -1505,11 +1595,37 @@ ms@^2.1.3:
1505
1595
  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
1506
1596
  integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
1507
1597
 
1598
+ msgpackr-extract@^3.0.2:
1599
+ version "3.0.3"
1600
+ resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz#e9d87023de39ce714872f9e9504e3c1996d61012"
1601
+ integrity sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==
1602
+ dependencies:
1603
+ node-gyp-build-optional-packages "5.2.2"
1604
+ optionalDependencies:
1605
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64" "3.0.3"
1606
+ "@msgpackr-extract/msgpackr-extract-darwin-x64" "3.0.3"
1607
+ "@msgpackr-extract/msgpackr-extract-linux-arm" "3.0.3"
1608
+ "@msgpackr-extract/msgpackr-extract-linux-arm64" "3.0.3"
1609
+ "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.3"
1610
+ "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.3"
1611
+
1612
+ msgpackr@^1.11.2:
1613
+ version "1.11.12"
1614
+ resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.11.12.tgz#52ca309b13a66f05443413794ab37bb6217a4425"
1615
+ integrity sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==
1616
+ optionalDependencies:
1617
+ msgpackr-extract "^3.0.2"
1618
+
1508
1619
  natural-compare@^1.4.0:
1509
1620
  version "1.4.0"
1510
1621
  resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
1511
1622
  integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
1512
1623
 
1624
+ node-addon-api@^6.1.0:
1625
+ version "6.1.0"
1626
+ resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76"
1627
+ integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==
1628
+
1513
1629
  node-forge@^1.3.1:
1514
1630
  version "1.3.3"
1515
1631
  resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.3.tgz#0ad80f6333b3a0045e827ac20b7f735f93716751"
@@ -1522,6 +1638,13 @@ node-gyp-build-optional-packages@5.1.1:
1522
1638
  dependencies:
1523
1639
  detect-libc "^2.0.1"
1524
1640
 
1641
+ node-gyp-build-optional-packages@5.2.2:
1642
+ version "5.2.2"
1643
+ resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz#522f50c2d53134d7f3a76cd7255de4ab6c96a3a4"
1644
+ integrity sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==
1645
+ dependencies:
1646
+ detect-libc "^2.0.1"
1647
+
1525
1648
  normalize-url@^6.0.1:
1526
1649
  version "6.1.0"
1527
1650
  resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
@@ -1560,6 +1683,11 @@ optionator@^0.9.3:
1560
1683
  type-check "^0.4.0"
1561
1684
  word-wrap "^1.2.5"
1562
1685
 
1686
+ ordered-binary@^1.5.3:
1687
+ version "1.6.1"
1688
+ resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.6.1.tgz#5ac240ea719d6a0e6d4f0485385d3f9cb1cd4432"
1689
+ integrity sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==
1690
+
1563
1691
  p-cancelable@^2.0.0:
1564
1692
  version "2.1.1"
1565
1693
  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
@@ -1812,10 +1940,10 @@ slash@^3.0.0:
1812
1940
  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
1813
1941
  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
1814
1942
 
1815
- socket-function@^1.0.1:
1816
- version "1.0.1"
1817
- resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.0.1.tgz#0fb37346c3395661c2c82a00a34908e1e5ed00bc"
1818
- integrity sha512-qsiDZxYEwLtSoX+/tlSfR5bE6YUNTdV+ccs+swtZFHsTajx3PhWnTvQRdgE2AnSwhtrldv3QOmZJsOTOZKL0/A==
1943
+ socket-function@^1.1.30:
1944
+ version "1.1.30"
1945
+ resolved "https://registry.yarnpkg.com/socket-function/-/socket-function-1.1.30.tgz#adeb9614996e727518e2abdc7a1aa90544d669cd"
1946
+ integrity sha512-EcqNpM8i0icBr2iU80aovXI05aUBrB4P4e9U7EQyju68TGAMagdA4OQXi+V1MHUipH/3nIdw3UAVYv+kFwZwnQ==
1819
1947
  dependencies:
1820
1948
  "@types/pako" "^2.0.3"
1821
1949
  "@types/ws" "^8.5.3"
@@ -1826,6 +1954,8 @@ socket-function@^1.0.1:
1826
1954
  typedev "^0.4.0"
1827
1955
  typenode "^6.0.1"
1828
1956
  ws "^8.17.1"
1957
+ optionalDependencies:
1958
+ lmdb "^3.5.1"
1829
1959
 
1830
1960
  source-map-js@^0.6.2:
1831
1961
  version "0.6.2"
@@ -1998,6 +2128,11 @@ uri-js@^4.2.2:
1998
2128
  dependencies:
1999
2129
  punycode "^2.1.0"
2000
2130
 
2131
+ weak-lru-cache@^1.2.2:
2132
+ version "1.2.2"
2133
+ resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19"
2134
+ integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==
2135
+
2001
2136
  which-module@^2.0.0:
2002
2137
  version "2.0.1"
2003
2138
  resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409"
package/.cursorrules DELETED
@@ -1,251 +0,0 @@
1
- The code automatically updates on save, so do not ever run commands to rerun the site.
2
-
3
- Don't run shell commands when you need to create or move small code files. You should use tool calls to do this. You should also use tool calls to make files within folders. You don't need to make the folder, just make the file. The folder will automatically be created.
4
-
5
- We use MobX for state management. Components should use a variable called synced that is an observable for their state, and never Component.state. All components need the @observer decorator. For example:
6
- import preact from "preact";
7
- import { observable } from "mobx";
8
-
9
- @observer
10
- class Example extends preact.Component {
11
- synced = observable({
12
- x: 0,
13
- });
14
-
15
- render() {
16
- return <div>
17
- <button onClick={() => this.synced.x++}>
18
- Click me
19
- </button>
20
- <p>
21
- {this.synced.x}
22
- </p>
23
- </div>;
24
- }
25
- }
26
-
27
- The code automatically updates on save, so do not ever run commands to rerun the site.
28
-
29
- If you need to add a dependency, don't just change the packs to JSON file. Properly use yarn add so you get the latest version, unless the user specifies a version or tells you otherwise.
30
-
31
- Use tool calls to read files and directories where possible, instead of running "ls", "dir", etc.
32
-
33
- Coding Styles
34
- Times should almost always be in milliseconds, and if not told, you should assume a time is in milliseconds.
35
-
36
- Don't make functions that will never be reused and are short. This just makes the code too confusing. If the function is under five lines and it's not being reused, you shouldn't create it, unless instructed explicitly to create it.
37
-
38
- Comments should be used sparingly and only if it's required to explain what's being done. If you're calling a function called create imageName and the comment is called create imageName, you will be fired because that's just stupid. It's a waste of lines.
39
-
40
- Comments go in the line before, never after the semicolon.
41
-
42
- Try not to use "null", and instead always use "undefined".
43
-
44
- Almost never check for undefined or null, just check for falsey.
45
-
46
- When functions have more than one primitive parameter, such that you could confuse them, even something as simple as start time and end time, you should put them inside of an object and call that object config, so the function only has a single parameter.
47
-
48
- Never use return codes, always prefer to throw on error. Include a lot of context information in the error. If any values might be extremely large, such as parsing a file, limit them (ex, to 500 characters).
49
-
50
- He used double quotes, not single quotes.
51
-
52
- Never use the ternary operator. Instead, do this: "x ? y : z" => "x && y || z".
53
-
54
- Never use non-null assertion operator, instead check the value, and if necessary (because it is accessed in nested functions), use a const variable to preserve the type.
55
-
56
- Errors should almost always use a template string to include the expected value, and the actual value, as in: "throw new Error(`Expected X, was ${Y}`);"
57
-
58
- Don't use switch statements. Use if/else statements instead.
59
-
60
- Don't use ! when accessing a value from a map. Use the get / if undefined initialize and set, and then use style. It's faster, and more type safe.
61
-
62
- Sort with this function, which takes a single function to map each object to a sortable value
63
- import { sort } from "socket-function/src/misc";
64
- export function sort<T>(arr: T[], sortKey: (obj: T) => unknown);
65
-
66
- Prefer to return, instead of using else statements. Handle error cases, warn/throw, and then return. Your main case should be below, not in an if statement, just in the main code.
67
-
68
- Use template strings for error messages, which include the exact value that triggered the error, and the exact expectation it failed.
69
-
70
- Use functions to prevent code duplication only when something is actually duplicated.
71
-
72
- Don't recreate collections or URL parameters, import them instead.
73
-
74
- Do not redefine types. Import the types correctly.
75
-
76
- Do not use types when they can be inferred.
77
-
78
- Constants that are arbitrary and that we might to reconfigure should be near the top of the file under the imports, not buried within functions.
79
-
80
- Never use environment variables. All configuration should be on the disk, or, if specific to a current run, passed as command line parameters.
81
-
82
- Never use inline styles, always use the CSS helper.
83
-
84
- Don't use `as any`.
85
-
86
- When you're making fetch calls and you get a type of any, you need to cast it to the actual type, and not leave it as any. The same goes for when you're deserializing values.
87
-
88
- DO NOT redeclare constants and copy their value. JUST IMPORT THEM!
89
-
90
- DO NOT redeclare types. JUST IMPORT THEM!
91
-
92
- Do not try catch for no reason. If you can't actually handle the exception, just let it throw.
93
-
94
- For input events, always use event.currentTarget.
95
-
96
- Use ref={elem => } callbacks. NEVER use .createRef.
97
-
98
- NEVER render images with a fixed width+height. This will cause them to be stretched or cut off. This is terrible. Only set the width or height.
99
-
100
- Callback held should be avoided by using async and `import { PromiseObj } from "socket-function/src/misc";`. Most of the time, if there's an event callback, you should wrap it with a promise obj so that you can wait for it asynchronously.
101
-
102
- `import { keyBy, keyByArray } from "socket-function/src/misc";` Should be used when you need to create lookups from lists and you know what key you want. This can clobber values, or it can gather in an array.
103
- let example: Map<number, { x: number }> = keyBy([{ x: 5 }, { x: 6 }]);
104
- let example: Map<number, { x: number }[]> = keyByArrat([{ x: 5 }, { x: 5, version: 2 } { x: 6 }]);
105
-
106
- Never use alert. If there's an error, you should throw it.
107
-
108
-
109
-
110
- General Styling
111
- Never use em or rem. Only use px or vw/vh/%.
112
-
113
- Don't add font colors unless asked to add styling. Don't add any aethetics beyond hbox/vbox/pad2 unless asked to add styling. Don't add fontSize unless asked to add styling. If you believe styling is possible, just tell the user, I can add styling, but won't do it unless you ask me to.
114
-
115
- Never use h1/h2/h3 etc. These classes have extremely large built-in margins and paddings, instead set the font size explicitly.
116
-
117
- Make sure to not use fillWidth, where flexGrow(1) would suffice.
118
-
119
- Components
120
- Anchor (<a> tag), for linking using URLParam
121
- <Anchor
122
- params={[[todolistURL, listKey]]}
123
- >
124
- {list.name}
125
- </Anchor>
126
- URLParam, Parameters which are stored in the URL. The second argument is the default, which can be a number, string, or an object. Set and get with .value
127
- const todolistURL = new URLParam("todolist", "");
128
-
129
- InputLabel and InputLabelURL should be used for inputs. For example:
130
- <InputLabelURL
131
- label="Show Previous Video"
132
- checkbox
133
- persisted={showPreviousVideoURL}
134
- />
135
- <InputLabel
136
- label="Notes"
137
- fillWidth
138
- value={node.notes || ""}
139
- onChangeValue={async (value) => {
140
- const updatedNode = deepCloneJSON(node);
141
- updatedNode.notes = value;
142
- await VideoNode.set(node.id, updatedNode);
143
- }}
144
- />
145
-
146
- API Calls
147
- When in an event callback (which must be async)
148
- APIController(getExtNodeId()).getModels.promise()
149
- When in a render function/context
150
- APIController(getExtNodeId()).getModels()
151
-
152
-
153
- DiskCollection
154
- If read an object from a collection, and then mutate it, and want to set it in the collection, you have to shallow copy it, so the DiskCollection picks up the change.
155
- let x = collection.get("x");
156
- x.y = Math.random();
157
- // Not asynchronous, as sets are synchronous
158
- collection.set("x", { ...x });
159
- The non-async functions should be called in render functions, the async functions should be called in event handlers, etc. Except for .set, which should be called in all both cases.
160
- get(key: string): T | undefined;
161
- async getPromise(key: string): Promise<T | undefined>;
162
- set(key: string, value: T): void;
163
- remove(key: string): void;
164
- getKeys(): string[];
165
- getKeysPromise(): Promise<string[]>;
166
- getEntries(): [string, T][];
167
- getValues(): T[];
168
- async getValuesPromise(): Promise<T[]>;
169
- getInfo(key: string);
170
- async reset();
171
-
172
- css
173
- Add very little styling, such as colours, rounding, etc, unless asked to add more styling.
174
-
175
- css should be set using className={css.cssPropertyName(cssPropertyValue).anotherPropertyName...}
176
- Always use the "css" helper for styling. For example:
177
- <div className={css.width(100).height(50)}>My width is 100px, my height is 50px</div>
178
- All css fields can be set in this way, with the function being the field name and the argument being the value.
179
- Generally speaking, the CSS helpers are on two lines. Wrapping is fine.
180
- className={css.size(100, 100).hbox(4)
181
- .hsl(0, 50, 50).borderRadius(4)
182
- }
183
- position
184
- - Position, size, font size, layout, hints, etc.
185
- - The cursor, color, font color, border radius, pointer, bold.
186
-
187
- Conditionals come after, and should use this style:
188
- className={css
189
- ...
190
- + (conditionalExample && css.opacity(0.5))
191
- }
192
- Specifically, it should be a value that you check for, and then the value. Don't use ternary, don't do `|| ""`
193
- - If you have multiple values, chain them with || and &&
194
- Keep the CSS simple, don't add too much, because it's easier to add than to remove.
195
-
196
- However, there are some helper functions that will directly map to commonly used styles.
197
-
198
- If you want to make a NON-Button feel like a button, you can use "css.button", which makes the background color change on hover, and make the cursor a pointer. Only use this if the background color is set, otherwise you need to message it's a button in another way. And never use it for <Button>/<button> which already does this.
199
-
200
- Generally use hbox/vbox to set the spacing between elements, instead of using margins.
201
-
202
-
203
- There are also some special aliases, some of which take parameters, some of which don't (which allows them to be chained like so: css.vbox0.wrap):
204
- let nonCallAliases = {
205
- relative: (c: CSSHelperTypeBase) => c.position("relative"),
206
- absolute: (c: CSSHelperTypeBase) => c.position("absolute"),
207
- fixed: (c: CSSHelperTypeBase) => c.position("fixed"),
208
- wrap: (c: CSSHelperTypeBase) => c.flexWrap("wrap").display("flex", "soft").alignItems("center", "soft"),
209
- marginAuto: (c: CSSHelperTypeBase) => c.margin("auto"),
210
- fillBoth: (c: CSSHelperTypeBase) => c.width("100%").height("100%"),
211
- fillWidth: (c: CSSHelperTypeBase) => c.width("100%"),
212
- fillHeight: (c: CSSHelperTypeBase) => c.height("100%"),
213
- flexShrink0: (c: CSSHelperTypeBase) => c.flexShrink(0),
214
- ellipsis: (c: CSSHelperTypeBase) => c.overflow("hidden").textOverflow("ellipsis").whiteSpace("nowrap").display("inline-block"),
215
- overflowAuto: (c: CSSHelperTypeBase) => c.overflow("auto"),
216
- overflowHidden: (c: CSSHelperTypeBase) => c.overflow("hidden"),
217
- };
218
- let callAliases = {
219
- hbox: (c: CSSHelperTypeBase, gap: number, rowGap?: number) => c.display("flex").flexDirection("row").rowGap(rowGap ?? gap).columnGap(gap).alignItems("center", "soft"),
220
- vbox: (c: CSSHelperTypeBase, gap: number, columnGap?: number) => c.display("flex").flexDirection("column").rowGap(gap).columnGap(columnGap ?? gap).alignItems("start", "soft"),
221
- pad2: (c: CSSHelperTypeBase, value: number, verticalValue?: number): CSSHelperTypeBase => {
222
- if (verticalValue !== undefined) return c.padding(`${verticalValue}px ${value}px` as any);
223
- return c.padding(value);
224
- },
225
- hsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`),
226
- hslhover: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`, "hover"),
227
- hsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`),
228
- hslahover: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`, "hover"),
229
- bord: (c: CSSHelperTypeBase, width: number, color: string | { h: number; s: number; l: number; a?: number; }, style = "solid"): CSSHelperTypeBase => {
230
- let colorStr = typeof color === "string" ? color : `hsla(${color.h}, ${color.s}%, ${color.l}%, ${color.a ?? 1})`;
231
- return c.border(`${width}px ${style} ${colorStr}`);
232
- },
233
- bord2: (c: CSSHelperTypeBase, h: number, s: number, l: number, width = 1, style = "solid"): CSSHelperTypeBase => {
234
- return c.border(`${width}px ${style} hsla(${h}, ${s}%, ${l}%, 1)`);
235
- },
236
- hslcolor: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
237
- colorhsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
238
- hslacolor: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
239
- colorhsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
240
- size: (c: CSSHelperTypeBase, width: LengthOrPercentage, height: LengthOrPercentage) => c.width(width).height(height),
241
- pos: (c: CSSHelperTypeBase, x: LengthOrPercentage, y: LengthOrPercentage) => c.left(x).top(y),
242
- };
243
-
244
-
245
- For animation keyframes, a style tag is required.
246
- <style>{`
247
- @keyframes spinner-ring {
248
- 0% { transform: rotate(0deg); }
249
- 100% { transform: rotate(360deg); }
250
- }
251
- `}</style>