querysub 0.431.0 → 0.433.0
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/.cursor/rules/css.mdc +58 -0
- package/.cursor/rules/general.mdc +35 -0
- package/.cursor/rules/react.mdc +27 -0
- package/package.json +2 -2
- package/src/-f-node-discovery/NodeDiscovery.ts +1 -2
- package/src/-h-path-value-serialize/PathValueSerializer.ts +1056 -1056
- package/src/0-path-value-core/pathValueCore.ts +1 -1
- package/src/2-proxy/PathValueProxyWatcher.ts +4 -0
- package/src/2-proxy/schema2.ts +1 -1
- package/src/3-path-functions/pathFunctionLoader.ts +4 -0
- package/src/4-querysub/Querysub.ts +3 -2
- package/src/misc/PromiseRace.ts +0 -101
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: CSS and Styling rules
|
|
3
|
+
globs: *
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# CSS and Styling Rules
|
|
8
|
+
|
|
9
|
+
- Never use `<h2>`, `<h3>`, etc, they have bad styling.
|
|
10
|
+
- 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.
|
|
11
|
+
- General use hbox/vbox to set the spacing between elements, instead of using margins.
|
|
12
|
+
- Never use em or rem. Only use px or vw/vh/%.
|
|
13
|
+
- 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.
|
|
14
|
+
- css should be set using `className={css.cssPropertyName(cssPropertyValue).anotherPropertyName...}`
|
|
15
|
+
- 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`):
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
let nonCallAliases = {
|
|
19
|
+
relative: (c: CSSHelperTypeBase) => c.position("relative"),
|
|
20
|
+
absolute: (c: CSSHelperTypeBase) => c.position("absolute"),
|
|
21
|
+
fixed: (c: CSSHelperTypeBase) => c.position("fixed"),
|
|
22
|
+
wrap: (c: CSSHelperTypeBase) => c.flexWrap("wrap").display("flex", "soft").alignItems("center", "soft"),
|
|
23
|
+
marginAuto: (c: CSSHelperTypeBase) => c.margin("auto"),
|
|
24
|
+
fillBoth: (c: CSSHelperTypeBase) => c.width("100%").height("100%"),
|
|
25
|
+
fillWidth: (c: CSSHelperTypeBase) => c.width("100%"),
|
|
26
|
+
fillHeight: (c: CSSHelperTypeBase) => c.height("100%"),
|
|
27
|
+
flexShrink0: (c: CSSHelperTypeBase) => c.flexShrink(0),
|
|
28
|
+
ellipsis: (c: CSSHelperTypeBase) => c.overflow("hidden").textOverflow("ellipsis").whiteSpace("nowrap").display("inline-block"),
|
|
29
|
+
overflowAuto: (c: CSSHelperTypeBase) => c.overflow("auto"),
|
|
30
|
+
overflowHidden: (c: CSSHelperTypeBase) => c.overflow("hidden"),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let callAliases = {
|
|
34
|
+
hbox: (c: CSSHelperTypeBase, gap: number, rowGap?: number) => c.display("flex").flexDirection("row").rowGap(rowGap ?? gap).columnGap(gap).alignItems("center", "soft"),
|
|
35
|
+
vbox: (c: CSSHelperTypeBase, gap: number, columnGap?: number) => c.display("flex").flexDirection("column").rowGap(gap).columnGap(columnGap ?? gap).alignItems("start", "soft"),
|
|
36
|
+
pad2: (c: CSSHelperTypeBase, value: number, verticalValue?: number): CSSHelperTypeBase => {
|
|
37
|
+
if (verticalValue !== undefined) return c.padding(`${verticalValue}px ${value}px` as any);
|
|
38
|
+
return c.padding(value);
|
|
39
|
+
},
|
|
40
|
+
hsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`),
|
|
41
|
+
hslhover: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.background(`hsl(${h}, ${s}%, ${l}%)`, "hover"),
|
|
42
|
+
hsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
43
|
+
hslahover: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.background(`hsla(${h}, ${s}%, ${l}%, ${a})`, "hover"),
|
|
44
|
+
bord: (c: CSSHelperTypeBase, width: number, color: string | { h: number; s: number; l: number; a?: number; }, style = "solid"): CSSHelperTypeBase => {
|
|
45
|
+
let colorStr = typeof color === "string" ? color : `hsla(${color.h}, ${color.s}%, ${color.l}%, ${color.a ?? 1})`;
|
|
46
|
+
return c.border(`${width}px ${style} ${colorStr}`);
|
|
47
|
+
},
|
|
48
|
+
bord2: (c: CSSHelperTypeBase, h: number, s: number, l: number, width = 1, style = "solid"): CSSHelperTypeBase => {
|
|
49
|
+
return c.border(`${width}px ${style} hsla(${h}, ${s}%, ${l}%, 1)`);
|
|
50
|
+
},
|
|
51
|
+
hslcolor: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
|
|
52
|
+
colorhsl: (c: CSSHelperTypeBase, h: number, s: number, l: number): CSSHelperTypeBase => c.color(`hsl(${h}, ${s}%, ${l}%)`),
|
|
53
|
+
hslacolor: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
54
|
+
colorhsla: (c: CSSHelperTypeBase, h: number, s: number, l: number, a: number): CSSHelperTypeBase => c.color(`hsla(${h}, ${s}%, ${l}%, ${a})`),
|
|
55
|
+
size: (c: CSSHelperTypeBase, width: LengthOrPercentage, height: LengthOrPercentage) => c.width(width).height(height),
|
|
56
|
+
pos: (c: CSSHelperTypeBase, x: LengthOrPercentage, y: LengthOrPercentage) => c.left(x).top(y),
|
|
57
|
+
};
|
|
58
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: General Typescript and coding rules
|
|
3
|
+
globs: *
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# General Rules
|
|
8
|
+
|
|
9
|
+
- The code automatically updates on save, so you do not need to ever run commands to run the site.
|
|
10
|
+
- NEVER copy and paste code. Use functions correctly, unless making it a function is more code than not making it a function.
|
|
11
|
+
- Unless schema values use atomic or type they will always be returned as a value (as a proxy). Use "in" to check if a value is in a `t.lookup`.
|
|
12
|
+
- Use double quotes.
|
|
13
|
+
- When running a command in the current project, don't "cd" to it. It's redundant, and won't work.
|
|
14
|
+
- Use the tool calls in order to modify files. Don't try to run terminal commands to modify files.
|
|
15
|
+
- Don't use redundant comments. If it's a single line and the function name says the same thing that the comment is going to say, you don't need the comment.
|
|
16
|
+
- When you're inline passing a lambda as an argument, never specify the type. The type should always be inferred. Specifying the type is bad, and it's hard coding, and we don't like hard coding.
|
|
17
|
+
- Follow the rule of minimum scoping. If something can be a local variable, it should be a local variable, it shouldn't be a class variable. If it can be a class variable, it should be a class variable, not a state variable. Etc, etc. Keep it simple, reference things closer, and write less code.
|
|
18
|
+
- Try not to use "null", and instead always use "undefined".
|
|
19
|
+
- Use square brackets for arrays, not a generic.
|
|
20
|
+
- USE: `T[]`
|
|
21
|
+
- NEVER: `Array<T>`
|
|
22
|
+
- Never try to add dynamic pluralization in the UI, just use an s. If you add dynamic pluralization, if the code ever gets localized, all of your changes have to be undone, and you just made localization much harder.
|
|
23
|
+
- Never use the ternary operator. Instead, do this: `x ? y : z` => `x && y || z`.
|
|
24
|
+
- The site automatically builds and hotreloads. Just save the files. DO NOT try to run any build scripts, because it automatically builds on save. DO NOT RUN "npm run build". DO NOT TRY TO RUN UNIT TESTS. DO NOT TRY TO RUN TESTS.
|
|
25
|
+
- When checking for if a value lies within a range, compare like so: `start <= pos && pos < end`. Specifically, making the pos in the middle.
|
|
26
|
+
- 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.
|
|
27
|
+
- 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}\`);`
|
|
28
|
+
- Don't use switch statements. Use if statements instead.
|
|
29
|
+
- 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.
|
|
30
|
+
- NEVER use the non-null assertion operator. Null check correctly, using const if required to preserve the assertion.
|
|
31
|
+
- Sort with this function, which takes a single function to map each object to a sortable value:
|
|
32
|
+
```typescript
|
|
33
|
+
import { sort } from "socket-function/src/misc";
|
|
34
|
+
export function sort<T>(arr: T[], sortKey: (obj: T) => unknown);
|
|
35
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: React and State Management rules
|
|
3
|
+
globs: *
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# React and State Rules
|
|
8
|
+
|
|
9
|
+
- Always directly set the state (`this.state.x = 1`), and never use `setState`.
|
|
10
|
+
- NEVER EVER pass state to `qreact.Component` as a template parameter. It should ALSO be declared like so (inside the class):
|
|
11
|
+
```typescript
|
|
12
|
+
state = t.state({
|
|
13
|
+
num: t.number,
|
|
14
|
+
nested: {
|
|
15
|
+
atomicObj: t.atomic<{ nestedAtomicField: number }>;
|
|
16
|
+
k: t.string
|
|
17
|
+
},
|
|
18
|
+
// All lookups are keyed by string
|
|
19
|
+
// (There is no t.array, arrays are not allowed, unless they are inside t.atomic)
|
|
20
|
+
lookup: t.lookup({
|
|
21
|
+
userName: t.string
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
- `t.lookup` objects cannot be set with `this.state.someLookup = {}`. You can add keys or remove keys, and keys are added implicitly (`this.state.someLookup["someKey"] = { x: 1, y: 1 }`, always works, the key is automatically added if it doesn't exist). Removal uses delete `delete this.state.someLookup["someKey"]`.
|
|
26
|
+
- If are inside an async Event Handlers, you need to use... `Querysub.onCommitFinished(() => ...)` and put the async code inside the callback. Then when you set state, you need to put the state setting code inside of `Querysub.commit(() => ...)`.
|
|
27
|
+
- Use `<InputLabel />` (from "querysub/src/library-components/InputLabel"), instead of `<input />`. Use `<InputLabel textarea />` instead of `<textarea />`. The input props of this allow you to set a label with "label", to act as a number with "number", as an integer with "integer", as a checkbox with "checkbox", and allow clicking to edit with "edit". There is a callback called "onChangeValue" which returns new values (as opposed to the entire event), which is useful.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "querysub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.433.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"pako": "^2.1.0",
|
|
63
63
|
"peggy": "^5.0.6",
|
|
64
64
|
"querysub": "^0.357.0",
|
|
65
|
-
"socket-function": "^1.1.
|
|
65
|
+
"socket-function": "^1.1.20",
|
|
66
66
|
"terser": "^5.31.0",
|
|
67
67
|
"typesafecss": "^0.28.0",
|
|
68
68
|
"yaml": "^2.5.0",
|
|
@@ -331,8 +331,7 @@ async function syncArchives() {
|
|
|
331
331
|
// Make sure we are present
|
|
332
332
|
await writeHeartbeat();
|
|
333
333
|
let nodeIds = await archives().find("");
|
|
334
|
-
console.
|
|
335
|
-
console.log(green(`Synced node ids from archives`), { nodeIds });
|
|
334
|
+
console.info(`Synced node ids from archives`, { nodeIds });
|
|
336
335
|
await setNodeIds(nodeIds);
|
|
337
336
|
} else {
|
|
338
337
|
if (isNoNetwork() || !isNode()) {
|