sliftutils 0.1.1
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.
- package/.cursorrules +161 -0
- package/.eslintrc.js +38 -0
- package/.vscode/settings.json +39 -0
- package/bundler/buffer.js +2370 -0
- package/bundler/bundleEntry.ts +32 -0
- package/bundler/bundleEntryCaller.ts +8 -0
- package/bundler/bundleRequire.ts +244 -0
- package/bundler/bundleWrapper.ts +115 -0
- package/bundler/bundler.ts +72 -0
- package/bundler/flattenSourceMaps.ts +0 -0
- package/bundler/sourceMaps.ts +261 -0
- package/misc/environment.ts +11 -0
- package/misc/types.ts +3 -0
- package/misc/zip.ts +37 -0
- package/package.json +24 -0
- package/spec.txt +33 -0
- package/storage/CachedStorage.ts +32 -0
- package/storage/DelayedStorage.ts +30 -0
- package/storage/DiskCollection.ts +272 -0
- package/storage/FileFolderAPI.tsx +427 -0
- package/storage/IStorage.ts +40 -0
- package/storage/IndexedDBFileFolderAPI.ts +170 -0
- package/storage/JSONStorage.ts +35 -0
- package/storage/PendingManager.tsx +63 -0
- package/storage/PendingStorage.ts +47 -0
- package/storage/PrivateFileSystemStorage.ts +192 -0
- package/storage/StorageObservable.ts +122 -0
- package/storage/TransactionStorage.ts +485 -0
- package/storage/fileSystemPointer.ts +81 -0
- package/storage/storage.d.ts +41 -0
- package/tsconfig.json +31 -0
- package/web/DropdownCustom.tsx +150 -0
- package/web/FullscreenModal.tsx +75 -0
- package/web/GenericFormat.tsx +186 -0
- package/web/Input.tsx +350 -0
- package/web/InputLabel.tsx +288 -0
- package/web/InputPicker.tsx +158 -0
- package/web/LocalStorageParam.ts +56 -0
- package/web/SyncedController.ts +405 -0
- package/web/SyncedLoadingIndicator.tsx +37 -0
- package/web/Table.tsx +188 -0
- package/web/URLParam.ts +84 -0
- package/web/asyncObservable.ts +40 -0
- package/web/colors.tsx +14 -0
- package/web/mobxTyped.ts +29 -0
- package/web/modal.tsx +18 -0
- package/web/observer.tsx +35 -0
package/.cursorrules
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
The code automatically updates on save, so do not ever run commands to rerun the site.
|
|
2
|
+
|
|
3
|
+
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:
|
|
4
|
+
import preact from "preact";
|
|
5
|
+
import { observable } from "mobx";
|
|
6
|
+
|
|
7
|
+
@observer
|
|
8
|
+
class Example extends preact.Component {
|
|
9
|
+
synced = observable({
|
|
10
|
+
x: 0,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
render() {
|
|
14
|
+
return <div>
|
|
15
|
+
<button onClick={() => this.synced.x++}>
|
|
16
|
+
Click me
|
|
17
|
+
</button>
|
|
18
|
+
<p>
|
|
19
|
+
{this.synced.x}
|
|
20
|
+
</p>
|
|
21
|
+
</div>;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Coding Styles
|
|
26
|
+
Try not to use "null", and instead always use "undefined".
|
|
27
|
+
|
|
28
|
+
He used double quotes, not single quotes.
|
|
29
|
+
|
|
30
|
+
Never use the ternary operator. Instead, do this: "x ? y : z" => "x && y || z".
|
|
31
|
+
|
|
32
|
+
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.
|
|
33
|
+
|
|
34
|
+
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}`);"
|
|
35
|
+
|
|
36
|
+
Don't use switch statements. Use if/else statements instead.
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
40
|
+
Sort with this function, which takes a single function to map each object to a sortable value
|
|
41
|
+
import { sort } from "socket-function/src/misc";
|
|
42
|
+
export function sort<T>(arr: T[], sortKey: (obj: T) => unknown);
|
|
43
|
+
|
|
44
|
+
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.
|
|
45
|
+
|
|
46
|
+
Use template strings for error messages, which include the exact value that triggered the error, and the exact expectation it failed.
|
|
47
|
+
|
|
48
|
+
Use functions to prevent code duplication only when something is actually duplicated.
|
|
49
|
+
|
|
50
|
+
Don't recreate collections or URL parameters, import them instead.
|
|
51
|
+
|
|
52
|
+
Do not redefine types. Import the types correctly.
|
|
53
|
+
|
|
54
|
+
Do not use types when they can be inferred.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
General Styling
|
|
58
|
+
Never use em or rem. Only use px or vw/vh/%.
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
|
|
62
|
+
Never use h1/h2/h3 etc. These classes have extremely large built-in margins and paddings, instead set the font size explicitly.
|
|
63
|
+
|
|
64
|
+
Make sure to not use fillWidth, where flexGrow(1) would suffice.
|
|
65
|
+
|
|
66
|
+
Components
|
|
67
|
+
Anchor (<a> tag), for linking using URLParam
|
|
68
|
+
<Anchor
|
|
69
|
+
params={[[todolistURL, listKey]]}
|
|
70
|
+
>
|
|
71
|
+
{list.name}
|
|
72
|
+
</Anchor>
|
|
73
|
+
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
|
|
74
|
+
const todolistURL = new URLParam("todolist", "");
|
|
75
|
+
|
|
76
|
+
API Calls
|
|
77
|
+
When in an event callback (which must be async)
|
|
78
|
+
APIController(getExtNodeId()).getModels.promise()
|
|
79
|
+
When in a render function/context
|
|
80
|
+
APIController(getExtNodeId()).getModels()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
css
|
|
85
|
+
css should be set using className={css.cssPropertyName(cssPropertyValue).anotherPropertyName...}
|
|
86
|
+
Always use the "css" helper for styling. For example:
|
|
87
|
+
<div className={css.width(100).height(50)}>My width is 100px, my height is 50px</div>
|
|
88
|
+
All css fields can be set in this way, with the function being the field name and the argument being the value.
|
|
89
|
+
Generally speaking, the CSS helpers are on two lines. Wrapping is fine.
|
|
90
|
+
className={css.size(100, 100).hbox(4)
|
|
91
|
+
.hsl(0, 50, 50).borderRadius(4)
|
|
92
|
+
}
|
|
93
|
+
position
|
|
94
|
+
- Position, size, font size, layout, hints, etc.
|
|
95
|
+
- The cursor, color, font color, border radius, pointer, bold.
|
|
96
|
+
|
|
97
|
+
Conditionals come after, and should use this style:
|
|
98
|
+
className={css
|
|
99
|
+
...
|
|
100
|
+
+ (conditionalExample && css.opacity(0.5))
|
|
101
|
+
}
|
|
102
|
+
Specifically, it should be a value that you check for, and then the value. Don't use ternary, don't do `|| ""`
|
|
103
|
+
- If you have multiple values, chain them with || and &&
|
|
104
|
+
Keep the CSS simple, don't add too much, because it's easier to add than to remove.
|
|
105
|
+
|
|
106
|
+
However, there are some helper functions that will directly map to commonly used styles.
|
|
107
|
+
|
|
108
|
+
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> which already does this.
|
|
109
|
+
|
|
110
|
+
Generally use hbox/vbox to set the spacing between elements, instead of using margins.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
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):
|
|
114
|
+
let nonCallAliases = {
|
|
115
|
+
relative: (c: CSSHelperTypeBase) => c.position("relative"),
|
|
116
|
+
absolute: (c: CSSHelperTypeBase) => c.position("absolute"),
|
|
117
|
+
fixed: (c: CSSHelperTypeBase) => c.position("fixed"),
|
|
118
|
+
wrap: (c: CSSHelperTypeBase) => c.flexWrap("wrap").display("flex", "soft").alignItems("center", "soft"),
|
|
119
|
+
marginAuto: (c: CSSHelperTypeBase) => c.margin("auto"),
|
|
120
|
+
fillBoth: (c: CSSHelperTypeBase) => c.width("100%").height("100%"),
|
|
121
|
+
fillWidth: (c: CSSHelperTypeBase) => c.width("100%"),
|
|
122
|
+
fillHeight: (c: CSSHelperTypeBase) => c.height("100%"),
|
|
123
|
+
flexShrink0: (c: CSSHelperTypeBase) => c.flexShrink(0),
|
|
124
|
+
ellipsis: (c: CSSHelperTypeBase) => c.overflow("hidden").textOverflow("ellipsis").whiteSpace("nowrap").display("inline-block"),
|
|
125
|
+
overflowAuto: (c: CSSHelperTypeBase) => c.overflow("auto"),
|
|
126
|
+
overflowHidden: (c: CSSHelperTypeBase) => c.overflow("hidden"),
|
|
127
|
+
};
|
|
128
|
+
let callAliases = {
|
|
129
|
+
hbox: (c: CSSHelperTypeBase, gap: number, rowGap?: number) => c.display("flex").flexDirection("row").rowGap(rowGap ?? gap).columnGap(gap).alignItems("center", "soft"),
|
|
130
|
+
vbox: (c: CSSHelperTypeBase, gap: number, columnGap?: number) => c.display("flex").flexDirection("column").rowGap(gap).columnGap(columnGap ?? gap).alignItems("start", "soft"),
|
|
131
|
+
pad2: (c: CSSHelperTypeBase, value: number, verticalValue?: number): CSSHelperTypeBase => {
|
|
132
|
+
if (verticalValue !== undefined) return c.padding(`${verticalValue}px ${value}px` as any);
|
|
133
|
+
return c.padding(value);
|
|
134
|
+
},
|
|
135
|
+
hsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`),
|
|
136
|
+
hslhover: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`, "hover"),
|
|
137
|
+
hsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
138
|
+
hslahover: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`, "hover"),
|
|
139
|
+
bord: (c: CSSHelperTypeBase, width: number, color: string | { h: number; s: number; l: number; a?: number; }, style = "solid"): CSSHelperTypeBase => {
|
|
140
|
+
let colorStr = typeof color === "string" ? color : `hsla(${color.h}, ${color.s}%, ${color.l}%, ${color.a ?? 1})`;
|
|
141
|
+
return c.border(`${width}px ${style} ${colorStr}`);
|
|
142
|
+
},
|
|
143
|
+
bord2: (c: CSSHelperTypeBase, h: number, s: number, l: number, width = 1, style = "solid"): CSSHelperTypeBase => {
|
|
144
|
+
return c.border(`${width}px ${style} hsla(${h}, ${s}%, ${l}%, 1)`);
|
|
145
|
+
},
|
|
146
|
+
hslcolor: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
|
|
147
|
+
colorhsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
|
|
148
|
+
hslacolor: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
149
|
+
colorhsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
150
|
+
size: (c: CSSHelperTypeBase, width: LengthOrPercentage, height: LengthOrPercentage) => c.width(width).height(height),
|
|
151
|
+
pos: (c: CSSHelperTypeBase, x: LengthOrPercentage, y: LengthOrPercentage) => c.left(x).top(y),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
For animation keyframes, a style tag is required.
|
|
156
|
+
<style>{`
|
|
157
|
+
@keyframes spinner-ring {
|
|
158
|
+
0% { transform: rotate(0deg); }
|
|
159
|
+
100% { transform: rotate(360deg); }
|
|
160
|
+
}
|
|
161
|
+
`}</style>
|
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: {
|
|
4
|
+
browser: true,
|
|
5
|
+
es6: true,
|
|
6
|
+
node: true,
|
|
7
|
+
},
|
|
8
|
+
extends: [],
|
|
9
|
+
globals: {
|
|
10
|
+
Atomics: "readonly",
|
|
11
|
+
SharedArrayBuffer: "readonly",
|
|
12
|
+
},
|
|
13
|
+
overrides: [
|
|
14
|
+
{
|
|
15
|
+
files: ["src/**/*.ts", "src/**/*.tsx"],
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
parser: "@typescript-eslint/parser",
|
|
19
|
+
parserOptions: {
|
|
20
|
+
ecmaVersion: 2018,
|
|
21
|
+
sourceType: "module",
|
|
22
|
+
project: "./tsconfig.json",
|
|
23
|
+
tsconfigRootDir: __dirname,
|
|
24
|
+
},
|
|
25
|
+
plugins: ["@typescript-eslint"],
|
|
26
|
+
rules: {
|
|
27
|
+
"@typescript-eslint/no-floating-promises": ["error"],
|
|
28
|
+
quotes: [
|
|
29
|
+
"error",
|
|
30
|
+
"double",
|
|
31
|
+
{
|
|
32
|
+
allowTemplateLiterals: true,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
eqeqeq: "error",
|
|
36
|
+
semi: "error",
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
// "debug.node.autoAttach": "on",
|
|
3
|
+
"files.watcherExclude": {
|
|
4
|
+
"**/.git/objects/**": true,
|
|
5
|
+
"**/.git/subtree-cache/**": true,
|
|
6
|
+
"**/node_modules/*/**": true,
|
|
7
|
+
"**/.hg/store/**": true
|
|
8
|
+
},
|
|
9
|
+
"files.exclude": {
|
|
10
|
+
"**/.git": true,
|
|
11
|
+
"**/.svn": true,
|
|
12
|
+
"**/.hg": true,
|
|
13
|
+
"**/CVS": true,
|
|
14
|
+
"**/.DS_Store": true,
|
|
15
|
+
"**/Thumbs.db": true,
|
|
16
|
+
"submodules": true,
|
|
17
|
+
"venvplan": true,
|
|
18
|
+
"**/dist/**": true
|
|
19
|
+
},
|
|
20
|
+
"[typescript]": {
|
|
21
|
+
"editor.formatOnSave": true,
|
|
22
|
+
},
|
|
23
|
+
"[typescriptreact]": {
|
|
24
|
+
"editor.formatOnSave": true,
|
|
25
|
+
},
|
|
26
|
+
"[javascript]": {
|
|
27
|
+
"editor.formatOnSave": true,
|
|
28
|
+
},
|
|
29
|
+
"[json]": {
|
|
30
|
+
"editor.formatOnSave": true,
|
|
31
|
+
},
|
|
32
|
+
"typescript.tsdk": "./node_modules/typescript/lib",
|
|
33
|
+
"search.exclude": {
|
|
34
|
+
"**/node_modules": true,
|
|
35
|
+
"**/bower_components": true,
|
|
36
|
+
"**/*.code-search": true,
|
|
37
|
+
"**.cache": true
|
|
38
|
+
}
|
|
39
|
+
}
|