Linttttt
This commit is contained in:
parent
20ab699e38
commit
036414ab20
25 changed files with 2727 additions and 1380 deletions
9
.vscode/settings.json
vendored
Normal file
9
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "always",
|
||||
"source.fixAll.ts": "always"
|
||||
}
|
||||
}
|
|
@ -1,289 +1,270 @@
|
|||
{
|
||||
"rules": {
|
||||
// Perf
|
||||
"no-await-in-loop": "deny",
|
||||
"no-useless-call": "deny",
|
||||
"no-accumulating-spread": "deny",
|
||||
"no-array-index-key": "deny",
|
||||
"jsx-no-jsx-as-prop": "deny",
|
||||
"jsx-no-new-array-as-prop": "deny",
|
||||
"jsx-no-new-function-as-prop": "deny",
|
||||
"jsx-no-new-object-as-prop": "deny",
|
||||
"prefer-set-has": "deny",
|
||||
// Suspicious
|
||||
"no-extend-native": "deny",
|
||||
"no-new": "deny",
|
||||
"no-unexpected-multiline": "deny",
|
||||
"no-unneeded-ternary": "deny",
|
||||
"no-useless-concat": "deny",
|
||||
"no-useless-constructor": "deny",
|
||||
"no-absolute-path": "deny",
|
||||
"no-duplicates": "deny",
|
||||
"no-empty-named-blocks": "deny",
|
||||
"no-named-as-default": "deny",
|
||||
"no-named-as-default-member": "deny",
|
||||
"no-self-import": "deny",
|
||||
"no-commented-out-tests": "deny",
|
||||
"approx-constant": "deny",
|
||||
"misrefactored-assign-op": "deny",
|
||||
"no-async-endpoint-handlers": "deny",
|
||||
"no-promise-in-callback": "deny",
|
||||
"iframe-missing-sandbox": "deny",
|
||||
"jsx-no-comment-textnodes": "deny",
|
||||
"jsx-no-script-url": "deny",
|
||||
"no-namespace": "deny",
|
||||
"style-prop-object": "deny",
|
||||
"no-confusing-non-null-assertion": "deny",
|
||||
"no-extraneous-class": "deny",
|
||||
"no-unnecessary-type-constraint": "deny",
|
||||
"consistent-function-scoping": "deny",
|
||||
"prefer-add-event-listener": "deny",
|
||||
"require-post-message-target-origin": "deny",
|
||||
// Pedantic
|
||||
"array-callback-return": "deny",
|
||||
"eqeqeq": "deny",
|
||||
"max-classes-per-file": "deny",
|
||||
"max-depth": "deny",
|
||||
"max-lines": "deny",
|
||||
"max-lines-per-function": "deny",
|
||||
"max-nested-callbacks": "deny",
|
||||
"no-array-constructor": "deny",
|
||||
"no-case-declarations": "deny",
|
||||
"no-constructor-return": "deny",
|
||||
"no-else-return": "deny",
|
||||
"no-fallthrough": "deny",
|
||||
"no-inner-declarations": "deny",
|
||||
"no-lonely-if": "deny",
|
||||
"no-negated-condition": "deny",
|
||||
"no-new-wrappers": "deny",
|
||||
"no-object-constructor": "deny",
|
||||
"no-prototype-builtins": "deny",
|
||||
"no-redeclare": "deny",
|
||||
"no-self-compare": "deny",
|
||||
"no-throw-literal": "deny",
|
||||
"radix": "deny",
|
||||
"require-await": "deny",
|
||||
"sort-vars": "deny",
|
||||
"symbol-description": "deny",
|
||||
"max-dependencies": [
|
||||
"deny",
|
||||
{
|
||||
"max": 16
|
||||
}
|
||||
],
|
||||
"no-conditional-in-test": "deny",
|
||||
"require-param": "deny",
|
||||
"require-param-description": "deny",
|
||||
"require-param-name": "deny",
|
||||
"require-param-type": "deny",
|
||||
"require-returns": "deny",
|
||||
"require-returns-description": "deny",
|
||||
"require-returns-type": "deny",
|
||||
"checked-requires-onchange-or-readonly": "deny",
|
||||
"jsx-no-useless-fragment": "deny",
|
||||
"no-unescaped-entities": "deny",
|
||||
"rules-of-hooks": "deny",
|
||||
"ban-ts-comment": "deny",
|
||||
"ban-types": "deny",
|
||||
"no-unsafe-function-type": "deny",
|
||||
"prefer-enum-initializers": "deny",
|
||||
"prefer-ts-expect-error": "deny",
|
||||
"consistent-empty-array-spread": "deny",
|
||||
"escape-case": "deny",
|
||||
"explicit-length-check": "deny",
|
||||
"new-for-builtins": "deny",
|
||||
"no-hex-escape": "deny",
|
||||
"no-instanceof-array": "deny",
|
||||
"no-negation-in-equality-check": "deny",
|
||||
"no-new-buffer": "deny",
|
||||
"no-object-as-default-parameter": "deny",
|
||||
"no-static-only-class": "deny",
|
||||
"no-this-assignment": "deny",
|
||||
"no-typeof-undefined": "deny",
|
||||
"no-unreadable-iife": "deny",
|
||||
"no-useless-promise-resolve-reject": "deny",
|
||||
"no-useless-switch-case": "deny",
|
||||
"no-useless-undefined": "deny",
|
||||
"prefer-array-flat": "deny",
|
||||
"prefer-array-some": "deny",
|
||||
"prefer-blob-reading-methods": "deny",
|
||||
"prefer-code-point": "deny",
|
||||
"prefer-date-now": "deny",
|
||||
"prefer-dom-node-append": "deny",
|
||||
"prefer-dom-node-dataset": "deny",
|
||||
"prefer-dom-node-remove": "deny",
|
||||
"prefer-event-target": "deny",
|
||||
"prefer-math-min-max": "deny",
|
||||
"prefer-math-trunc": "deny",
|
||||
"prefer-native-coercion-functions": "deny",
|
||||
"prefer-prototype-methods": "deny",
|
||||
"prefer-query-selector": "deny",
|
||||
"prefer-regexp-test": "deny",
|
||||
"prefer-string-replace-all": "deny",
|
||||
"prefer-string-slice": "deny",
|
||||
"prefer-type-error": "deny",
|
||||
"require-number-to-fixed-digits-argument": "deny",
|
||||
// Style
|
||||
"curly": "deny",
|
||||
"default-case-last": "deny",
|
||||
"default-param-last": "deny",
|
||||
"func-names": "deny",
|
||||
"func-style": "deny",
|
||||
"grouped-accessor-pairs": "deny",
|
||||
"guard-for-in": "deny",
|
||||
"init-declarations": "deny",
|
||||
"max-params": "deny",
|
||||
"new-cap": "deny",
|
||||
"no-continue": "deny",
|
||||
"no-duplicate-imports": "deny",
|
||||
"no-extra-label": "deny",
|
||||
"no-label-var": "deny",
|
||||
"no-labels": "deny",
|
||||
"no-lone-blocks": "deny",
|
||||
"no-multi-assign": "deny",
|
||||
"no-multi-str": "deny",
|
||||
"no-nested-ternary": "deny",
|
||||
"no-new-func": "deny",
|
||||
"no-return-assign": "deny",
|
||||
"no-script-url": "deny",
|
||||
"no-template-curly-in-string": "deny",
|
||||
"no-ternary": "deny",
|
||||
"operator-assignment": "deny",
|
||||
"prefer-exponentiation-operator": "deny",
|
||||
"prefer-numeric-literals": "deny",
|
||||
"prefer-object-has-own": "deny",
|
||||
"prefer-object-spread": "deny",
|
||||
"prefer-promise-reject-errors": "deny",
|
||||
"prefer-rest-params": "deny",
|
||||
"sort-imports": "deny",
|
||||
"sort-keys": "deny",
|
||||
"vars-on-top": "deny",
|
||||
"yoda": "deny",
|
||||
"exports-last": "deny",
|
||||
"first": "deny",
|
||||
"no-anonymous-default-export": "deny",
|
||||
"no-mutable-exports": "deny",
|
||||
"no-named-default": "deny",
|
||||
"consistent-test-it": "deny",
|
||||
"max-expects": "deny",
|
||||
"max-nested-describe": "deny",
|
||||
"no-alias-methods": "deny",
|
||||
"no-confusing-set-timeout": "deny",
|
||||
"no-deprecated-functions": "deny",
|
||||
"no-done-callback": "deny",
|
||||
"no-duplicate-hooks": "deny",
|
||||
"no-hooks": "deny",
|
||||
"no-identical-title": "deny",
|
||||
"no-interpolation-in-snapshots": "deny",
|
||||
"no-jasmine-globals": "deny",
|
||||
"no-large-snapshots": "deny",
|
||||
"no-mocks-import": "deny",
|
||||
"no-restricted-jest-methods": "deny",
|
||||
"no-restricted-matchers": "deny",
|
||||
"no-test-prefixes": "deny",
|
||||
"no-test-return-statement": "deny",
|
||||
"no-untyped-mock-factory": "deny",
|
||||
"prefer-called-with": "deny",
|
||||
"prefer-comparison-matcher": "deny",
|
||||
"prefer-each": "deny",
|
||||
"prefer-equality-matcher": "deny",
|
||||
"prefer-expect-resolves": "deny",
|
||||
"prefer-hooks-in-order": "deny",
|
||||
"prefer-hooks-on-top": "deny",
|
||||
"prefer-jest-mocked": "deny",
|
||||
"prefer-lowercase-title": "deny",
|
||||
"prefer-mock-promise-shorthand": "deny",
|
||||
"prefer-spy-on": "deny",
|
||||
"prefer-strict-equal": "deny",
|
||||
"prefer-to-be": "deny",
|
||||
"prefer-to-contain": "deny",
|
||||
"prefer-to-have-length": "deny",
|
||||
"prefer-todo": "deny",
|
||||
"require-hook": "deny",
|
||||
"require-top-level-describe": "deny",
|
||||
"no-exports-assign": "deny",
|
||||
"no-nesting": "deny",
|
||||
"no-return-wrap": "deny",
|
||||
"param-names": "deny",
|
||||
"prefer-await-to-callbacks": "deny",
|
||||
"prefer-await-to-then": "deny",
|
||||
"prefer-catch": "deny",
|
||||
"jsx-boolean-value": "deny",
|
||||
"jsx-curly-brace-presence": "deny",
|
||||
"no-set-state": "deny",
|
||||
"prefer-es6-class": "deny",
|
||||
"self-closing-comp": "deny",
|
||||
"adjacent-overload-signatures": "deny",
|
||||
"array-type": "deny",
|
||||
"ban-tslint-comment": "deny",
|
||||
"consistent-generic-constructors": "deny",
|
||||
"consistent-indexed-object-style": "deny",
|
||||
"consistent-type-definitions": "deny",
|
||||
"no-empty-interface": "deny",
|
||||
"no-inferrable-types": "deny",
|
||||
"prefer-for-of": "deny",
|
||||
"prefer-function-type": "deny",
|
||||
"prefer-namespace-keyword": "deny",
|
||||
"catch-error-name": "deny",
|
||||
"consistent-date-clone": "deny",
|
||||
"consistent-existence-index-check": "deny",
|
||||
"empty-brace-spaces": "deny",
|
||||
"error-message": "deny",
|
||||
"filename-case": "deny",
|
||||
"no-await-expression-member": "deny",
|
||||
"no-console-spaces": "deny",
|
||||
"no-null": "deny",
|
||||
"no-unreadable-array-destructuring": "deny",
|
||||
"no-zero-fractions": "deny",
|
||||
"number-literal-case": "deny",
|
||||
"numeric-separators-style": "deny",
|
||||
"prefer-array-flat-map": "deny",
|
||||
"prefer-dom-node-text-content": "deny",
|
||||
"prefer-includes": "deny",
|
||||
"prefer-logical-operator-over-ternary": "deny",
|
||||
"prefer-modern-dom-apis": "deny",
|
||||
"prefer-negative-index": "deny",
|
||||
"prefer-optional-catch-binding": "deny",
|
||||
"prefer-reflect-apply": "deny",
|
||||
"prefer-spread": "deny",
|
||||
"prefer-string-raw": "deny",
|
||||
"prefer-string-trim-start-end": "deny",
|
||||
"prefer-structured-clone": "deny",
|
||||
"require-array-join-separator": "deny",
|
||||
"switch-case-braces": "deny",
|
||||
"text-encoding-identifier-case": "deny",
|
||||
"throw-new-error": "deny",
|
||||
"no-import-node-test": "deny",
|
||||
"prefer-to-be-falsy": "deny",
|
||||
"prefer-to-be-object": "deny",
|
||||
"prefer-to-be-truthy": "deny",
|
||||
// Nursery
|
||||
"getter-return": "deny",
|
||||
"no-undef": "deny",
|
||||
"no-unreachable": "deny",
|
||||
"export": "deny",
|
||||
"named": "deny",
|
||||
"no-map-spread": "deny",
|
||||
"no-return-in-finally": "deny",
|
||||
"exhaustive-deps": "deny",
|
||||
"require-render-return": "deny",
|
||||
"consistent-type-imports": "deny"
|
||||
},
|
||||
"plugins": [
|
||||
"typescript",
|
||||
"unicorn",
|
||||
"oxc",
|
||||
"import",
|
||||
"promise",
|
||||
"solid"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"src/bindings/"
|
||||
],
|
||||
"env": {
|
||||
"builtin": true,
|
||||
"browser": true,
|
||||
"es2024": true,
|
||||
"worker": true,
|
||||
}
|
||||
}
|
||||
"rules": {
|
||||
// Perf
|
||||
"no-await-in-loop": "deny",
|
||||
"no-useless-call": "deny",
|
||||
"no-accumulating-spread": "deny",
|
||||
"no-array-index-key": "deny",
|
||||
"jsx-no-jsx-as-prop": "deny",
|
||||
"jsx-no-new-array-as-prop": "deny",
|
||||
"jsx-no-new-function-as-prop": "deny",
|
||||
"jsx-no-new-object-as-prop": "deny",
|
||||
"prefer-set-has": "deny",
|
||||
// Suspicious
|
||||
"no-extend-native": "deny",
|
||||
"no-new": "deny",
|
||||
"no-unexpected-multiline": "deny",
|
||||
"no-unneeded-ternary": "deny",
|
||||
"no-useless-concat": "deny",
|
||||
"no-useless-constructor": "deny",
|
||||
"no-absolute-path": "deny",
|
||||
"no-duplicates": "deny",
|
||||
"no-empty-named-blocks": "deny",
|
||||
"no-named-as-default": "deny",
|
||||
"no-named-as-default-member": "deny",
|
||||
"no-self-import": "deny",
|
||||
"no-commented-out-tests": "deny",
|
||||
"approx-constant": "deny",
|
||||
"misrefactored-assign-op": "deny",
|
||||
"no-async-endpoint-handlers": "deny",
|
||||
"no-promise-in-callback": "deny",
|
||||
"iframe-missing-sandbox": "deny",
|
||||
"jsx-no-comment-textnodes": "deny",
|
||||
"jsx-no-script-url": "deny",
|
||||
"no-namespace": "deny",
|
||||
"style-prop-object": "deny",
|
||||
"no-confusing-non-null-assertion": "deny",
|
||||
"no-extraneous-class": "deny",
|
||||
"no-unnecessary-type-constraint": "deny",
|
||||
"consistent-function-scoping": "deny",
|
||||
"prefer-add-event-listener": "deny",
|
||||
"require-post-message-target-origin": "deny",
|
||||
// Pedantic
|
||||
"array-callback-return": "deny",
|
||||
"eqeqeq": "deny",
|
||||
"max-classes-per-file": "deny",
|
||||
"max-depth": "deny",
|
||||
"max-lines": "deny",
|
||||
"max-lines-per-function": "deny",
|
||||
"max-nested-callbacks": "deny",
|
||||
"no-array-constructor": "deny",
|
||||
"no-case-declarations": "deny",
|
||||
"no-constructor-return": "deny",
|
||||
"no-else-return": "deny",
|
||||
"no-fallthrough": "deny",
|
||||
"no-inner-declarations": "deny",
|
||||
"no-lonely-if": "deny",
|
||||
"no-negated-condition": "deny",
|
||||
"no-new-wrappers": "deny",
|
||||
"no-object-constructor": "deny",
|
||||
"no-prototype-builtins": "deny",
|
||||
"no-redeclare": "deny",
|
||||
"no-self-compare": "deny",
|
||||
"no-throw-literal": "deny",
|
||||
"radix": "deny",
|
||||
"require-await": "deny",
|
||||
"sort-vars": "deny",
|
||||
"symbol-description": "deny",
|
||||
"max-dependencies": ["deny", { "max": 16 }],
|
||||
"no-conditional-in-test": "deny",
|
||||
"require-param": "deny",
|
||||
"require-param-description": "deny",
|
||||
"require-param-name": "deny",
|
||||
"require-param-type": "deny",
|
||||
"require-returns": "deny",
|
||||
"require-returns-description": "deny",
|
||||
"require-returns-type": "deny",
|
||||
"checked-requires-onchange-or-readonly": "deny",
|
||||
"jsx-no-useless-fragment": "deny",
|
||||
"no-unescaped-entities": "deny",
|
||||
"rules-of-hooks": "deny",
|
||||
"ban-ts-comment": "deny",
|
||||
"ban-types": "deny",
|
||||
"no-unsafe-function-type": "deny",
|
||||
"prefer-enum-initializers": "deny",
|
||||
"prefer-ts-expect-error": "deny",
|
||||
"consistent-empty-array-spread": "deny",
|
||||
"escape-case": "deny",
|
||||
"explicit-length-check": "deny",
|
||||
"new-for-builtins": "deny",
|
||||
"no-hex-escape": "deny",
|
||||
"no-instanceof-array": "deny",
|
||||
"no-negation-in-equality-check": "deny",
|
||||
"no-new-buffer": "deny",
|
||||
"no-object-as-default-parameter": "deny",
|
||||
"no-static-only-class": "deny",
|
||||
"no-this-assignment": "deny",
|
||||
"no-typeof-undefined": "deny",
|
||||
"no-unreadable-iife": "deny",
|
||||
"no-useless-promise-resolve-reject": "deny",
|
||||
"no-useless-switch-case": "deny",
|
||||
"no-useless-undefined": "deny",
|
||||
"prefer-array-flat": "deny",
|
||||
"prefer-array-some": "deny",
|
||||
"prefer-blob-reading-methods": "deny",
|
||||
"prefer-code-point": "deny",
|
||||
"prefer-date-now": "deny",
|
||||
"prefer-dom-node-append": "deny",
|
||||
"prefer-dom-node-dataset": "deny",
|
||||
"prefer-dom-node-remove": "deny",
|
||||
"prefer-event-target": "deny",
|
||||
"prefer-math-min-max": "deny",
|
||||
"prefer-math-trunc": "deny",
|
||||
"prefer-native-coercion-functions": "deny",
|
||||
"prefer-prototype-methods": "deny",
|
||||
"prefer-query-selector": "deny",
|
||||
"prefer-regexp-test": "deny",
|
||||
"prefer-string-replace-all": "deny",
|
||||
"prefer-string-slice": "deny",
|
||||
"prefer-type-error": "deny",
|
||||
"require-number-to-fixed-digits-argument": "deny",
|
||||
// Style
|
||||
"curly": "deny",
|
||||
"default-case-last": "deny",
|
||||
"default-param-last": "deny",
|
||||
"func-names": "deny",
|
||||
"func-style": "deny",
|
||||
"grouped-accessor-pairs": "deny",
|
||||
"guard-for-in": "deny",
|
||||
"init-declarations": "deny",
|
||||
"max-params": "deny",
|
||||
"new-cap": "deny",
|
||||
"no-continue": "deny",
|
||||
"no-duplicate-imports": "deny",
|
||||
"no-extra-label": "deny",
|
||||
"no-label-var": "deny",
|
||||
"no-labels": "deny",
|
||||
"no-lone-blocks": "deny",
|
||||
"no-multi-assign": "deny",
|
||||
"no-multi-str": "deny",
|
||||
"no-nested-ternary": "deny",
|
||||
"no-new-func": "deny",
|
||||
"no-return-assign": "deny",
|
||||
"no-script-url": "deny",
|
||||
"no-template-curly-in-string": "deny",
|
||||
"no-ternary": "deny",
|
||||
"operator-assignment": "deny",
|
||||
"prefer-exponentiation-operator": "deny",
|
||||
"prefer-numeric-literals": "deny",
|
||||
"prefer-object-has-own": "deny",
|
||||
"prefer-object-spread": "deny",
|
||||
"prefer-promise-reject-errors": "deny",
|
||||
"prefer-rest-params": "deny",
|
||||
"sort-imports": "deny",
|
||||
"sort-keys": "deny",
|
||||
"vars-on-top": "deny",
|
||||
"yoda": "deny",
|
||||
"exports-last": "deny",
|
||||
"first": "deny",
|
||||
"no-anonymous-default-export": "deny",
|
||||
"no-mutable-exports": "deny",
|
||||
"no-named-default": "deny",
|
||||
"consistent-test-it": "deny",
|
||||
"max-expects": "deny",
|
||||
"max-nested-describe": "deny",
|
||||
"no-alias-methods": "deny",
|
||||
"no-confusing-set-timeout": "deny",
|
||||
"no-deprecated-functions": "deny",
|
||||
"no-done-callback": "deny",
|
||||
"no-duplicate-hooks": "deny",
|
||||
"no-hooks": "deny",
|
||||
"no-identical-title": "deny",
|
||||
"no-interpolation-in-snapshots": "deny",
|
||||
"no-jasmine-globals": "deny",
|
||||
"no-large-snapshots": "deny",
|
||||
"no-mocks-import": "deny",
|
||||
"no-restricted-jest-methods": "deny",
|
||||
"no-restricted-matchers": "deny",
|
||||
"no-test-prefixes": "deny",
|
||||
"no-test-return-statement": "deny",
|
||||
"no-untyped-mock-factory": "deny",
|
||||
"prefer-called-with": "deny",
|
||||
"prefer-comparison-matcher": "deny",
|
||||
"prefer-each": "deny",
|
||||
"prefer-equality-matcher": "deny",
|
||||
"prefer-expect-resolves": "deny",
|
||||
"prefer-hooks-in-order": "deny",
|
||||
"prefer-hooks-on-top": "deny",
|
||||
"prefer-jest-mocked": "deny",
|
||||
"prefer-lowercase-title": "deny",
|
||||
"prefer-mock-promise-shorthand": "deny",
|
||||
"prefer-spy-on": "deny",
|
||||
"prefer-strict-equal": "deny",
|
||||
"prefer-to-be": "deny",
|
||||
"prefer-to-contain": "deny",
|
||||
"prefer-to-have-length": "deny",
|
||||
"prefer-todo": "deny",
|
||||
"require-hook": "deny",
|
||||
"require-top-level-describe": "deny",
|
||||
"no-exports-assign": "deny",
|
||||
"no-nesting": "deny",
|
||||
"no-return-wrap": "deny",
|
||||
"param-names": "deny",
|
||||
"prefer-await-to-callbacks": "deny",
|
||||
"prefer-await-to-then": "deny",
|
||||
"prefer-catch": "deny",
|
||||
"jsx-boolean-value": "deny",
|
||||
"jsx-curly-brace-presence": "deny",
|
||||
"no-set-state": "deny",
|
||||
"prefer-es6-class": "deny",
|
||||
"self-closing-comp": "deny",
|
||||
"adjacent-overload-signatures": "deny",
|
||||
"array-type": "deny",
|
||||
"ban-tslint-comment": "deny",
|
||||
"consistent-generic-constructors": "deny",
|
||||
"consistent-indexed-object-style": "deny",
|
||||
"consistent-type-definitions": "deny",
|
||||
"no-empty-interface": "deny",
|
||||
"no-inferrable-types": "deny",
|
||||
"prefer-for-of": "deny",
|
||||
"prefer-function-type": "deny",
|
||||
"prefer-namespace-keyword": "deny",
|
||||
"catch-error-name": "deny",
|
||||
"consistent-date-clone": "deny",
|
||||
"consistent-existence-index-check": "deny",
|
||||
"empty-brace-spaces": "deny",
|
||||
"error-message": "deny",
|
||||
"filename-case": "deny",
|
||||
"no-await-expression-member": "deny",
|
||||
"no-console-spaces": "deny",
|
||||
"no-null": "deny",
|
||||
"no-unreadable-array-destructuring": "deny",
|
||||
"no-zero-fractions": "deny",
|
||||
"number-literal-case": "deny",
|
||||
"numeric-separators-style": "deny",
|
||||
"prefer-array-flat-map": "deny",
|
||||
"prefer-dom-node-text-content": "deny",
|
||||
"prefer-includes": "deny",
|
||||
"prefer-logical-operator-over-ternary": "deny",
|
||||
"prefer-modern-dom-apis": "deny",
|
||||
"prefer-negative-index": "deny",
|
||||
"prefer-optional-catch-binding": "deny",
|
||||
"prefer-reflect-apply": "deny",
|
||||
"prefer-spread": "deny",
|
||||
"prefer-string-raw": "deny",
|
||||
"prefer-string-trim-start-end": "deny",
|
||||
"prefer-structured-clone": "deny",
|
||||
"require-array-join-separator": "deny",
|
||||
"switch-case-braces": "deny",
|
||||
"text-encoding-identifier-case": "deny",
|
||||
"throw-new-error": "deny",
|
||||
"no-import-node-test": "deny",
|
||||
"prefer-to-be-falsy": "deny",
|
||||
"prefer-to-be-object": "deny",
|
||||
"prefer-to-be-truthy": "deny",
|
||||
// Nursery
|
||||
"getter-return": "deny",
|
||||
"no-undef": "deny",
|
||||
"no-unreachable": "deny",
|
||||
"export": "deny",
|
||||
"named": "deny",
|
||||
"no-map-spread": "deny",
|
||||
"no-return-in-finally": "deny",
|
||||
"exhaustive-deps": "deny",
|
||||
"require-render-return": "deny",
|
||||
"consistent-type-imports": "deny"
|
||||
},
|
||||
"plugins": ["typescript", "unicorn", "oxc", "import", "promise", "solid"],
|
||||
"ignorePatterns": ["src/bindings/"],
|
||||
"env": { "builtin": true, "browser": true, "es2024": true, "worker": true }
|
||||
}
|
||||
|
|
3
client/.prettierignore
Normal file
3
client/.prettierignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
dist
|
||||
node_modules
|
||||
src/bindings
|
34
client/eslint.config.ts
Normal file
34
client/eslint.config.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// eslint.config.js
|
||||
import eslint from "@eslint/js";
|
||||
import eslintConfigPrettier from "eslint-config-prettier";
|
||||
import oxlint from "eslint-plugin-oxlint";
|
||||
import solid from "eslint-plugin-solid/configs/typescript";
|
||||
import tseslint from "typescript-eslint";
|
||||
import unicorn from "eslint-plugin-unicorn";
|
||||
|
||||
export default [
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: [
|
||||
"src/bindings/",
|
||||
"dist/",
|
||||
"eslint.config.ts",
|
||||
"vite.config.ts",
|
||||
"prettier.config.js",
|
||||
],
|
||||
},
|
||||
{ rules: { "solid/no-array-handlers": "warn", "solid/prefer-show": "warn" } },
|
||||
solid,
|
||||
eslint.configs.recommended,
|
||||
unicorn.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
eslintConfigPrettier,
|
||||
...oxlint.buildFromOxlintConfigFile(".oxlintrc.json"),
|
||||
];
|
|
@ -5,16 +5,27 @@
|
|||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"preview": "vite preview"
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "oxlint && eslint && prettier . -c",
|
||||
"format": "oxlint --fix && eslint --fix && prettier . -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"@clockworklabs/spacetimedb-sdk": "^1.0.3",
|
||||
"solid-js": "^1.9.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.23.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.27.0",
|
||||
"eslint": "^9.23.0",
|
||||
"eslint-config-prettier": "^10.1.1",
|
||||
"eslint-plugin-oxlint": "^0.16.2",
|
||||
"eslint-plugin-solid": "^0.14.5",
|
||||
"eslint-plugin-unicorn": "^57.0.0",
|
||||
"jiti": "^2.4.2",
|
||||
"prettier": "^3.5.3",
|
||||
"typescript": "~5.7.3",
|
||||
"typescript-eslint": "^8.27.0",
|
||||
"vite": "^6.2.2",
|
||||
"vite-plugin-oxlint": "^1.3.0",
|
||||
"vite-plugin-solid": "^2.11.6"
|
||||
|
|
2857
client/pnpm-lock.yaml
generated
2857
client/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
22
client/prettier.config.js
Normal file
22
client/prettier.config.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
/** @type {import("prettier").Config} */
|
||||
const config = {
|
||||
arrowParens: "always",
|
||||
bracketSameLine: true,
|
||||
bracketSpacing: true,
|
||||
embeddedLanguageFormatting: "auto",
|
||||
endOfLine: "lf",
|
||||
experimentalOperatorPosition: "start",
|
||||
experimentalTernaries: true,
|
||||
htmlWhitespaceSensitivity: "strict",
|
||||
jsxSingleQuote: false,
|
||||
objectWrap: "collapse",
|
||||
proseWrap: "always",
|
||||
quoteProps: "consistent",
|
||||
semi: true,
|
||||
singleAttributePerLine: false,
|
||||
singleQuote: false,
|
||||
tabWidth: 2,
|
||||
trailingComma: "all",
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -1,4 +1,4 @@
|
|||
#root {
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
import './app.css'
|
||||
import "./app.css";
|
||||
|
||||
import { DbConnection, type Note as DbNote, type ErrorContext, type EventContext } from './bindings';
|
||||
import { For, Show, createEffect, createSignal } from 'solid-js'
|
||||
import { type Identity, Timestamp } from '@clockworklabs/spacetimedb-sdk'
|
||||
import { Note } from './lib';
|
||||
import {
|
||||
DbConnection as DatabaseConnection,
|
||||
type Note as DatabaseNote,
|
||||
type ErrorContext,
|
||||
type EventContext,
|
||||
} from "./bindings";
|
||||
import { For, Show, createEffect, createSignal } from "solid-js";
|
||||
import { type Identity, Timestamp } from "@clockworklabs/spacetimedb-sdk";
|
||||
import { Note } from "./library";
|
||||
|
||||
export async function wait(ms: number) {
|
||||
return await new Promise((resolve) => { setTimeout(resolve, ms) });
|
||||
return await new Promise((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
enum Status {
|
||||
|
@ -17,131 +24,160 @@ enum Status {
|
|||
}
|
||||
|
||||
export default function App() {
|
||||
const [connection, setConnection] = createSignal<DbConnection | undefined>();
|
||||
const [connection, setConnection] = createSignal<
|
||||
DatabaseConnection | undefined
|
||||
>();
|
||||
const [status, setStatus] = createSignal<Status>(Status.Connecting);
|
||||
const [notes, setNotes] = createSignal<Note[]>([])
|
||||
const [notes, setNotes] = createSignal<Note[]>([]);
|
||||
|
||||
const noteOnInsert = (_context: EventContext, row: DatabaseNote) => {
|
||||
const newNote = new Note(row);
|
||||
|
||||
// Asserting here that a newly inserted Note will always be at the end, and skip sorting
|
||||
setNotes([...notes(), newNote]);
|
||||
};
|
||||
|
||||
const noteOnUpdate = (
|
||||
_context: EventContext,
|
||||
oldRow: DatabaseNote,
|
||||
newRow: DatabaseNote,
|
||||
) => {
|
||||
const note = notes().find(({ id }) => id === oldRow.id);
|
||||
if (note) {
|
||||
console.debug("server setting", oldRow.id, "to", newRow.value);
|
||||
note.update(newRow);
|
||||
}
|
||||
};
|
||||
|
||||
const noteOnDelete = (_context: EventContext, row: DatabaseNote) => {
|
||||
console.debug("server deleting", row.id);
|
||||
setNotes(notes().filter(({ id }) => id !== row.id));
|
||||
};
|
||||
|
||||
const onDisconnect = (_context: ErrorContext, error?: Error) => {
|
||||
if (error) console.error("Disconnecting", error);
|
||||
else console.error("Disconnecting");
|
||||
setStatus(Status.Disconnected);
|
||||
const conn = connection();
|
||||
if (!conn) return;
|
||||
const note = conn.db.note;
|
||||
note.removeOnInsert(noteOnInsert);
|
||||
note.removeOnUpdate(noteOnUpdate);
|
||||
note.removeOnDelete(noteOnDelete);
|
||||
};
|
||||
|
||||
createEffect(() => {
|
||||
const noteOnInsert = (_ctx: EventContext, row: DbNote) => {
|
||||
const newNote = new Note(row);
|
||||
|
||||
// Asserting here that a newly inserted Note will always be at the end, and skip sorting
|
||||
setNotes([...notes(), newNote])
|
||||
}
|
||||
const noteOnUpdate = (_ctx: EventContext, oldRow: DbNote, newRow: DbNote) => {
|
||||
const note = notes().find(({id}) => id === oldRow.id);
|
||||
if (note) {
|
||||
console.debug("server setting", oldRow.id, "to", newRow.value)
|
||||
note.update(newRow);
|
||||
}
|
||||
};
|
||||
const noteOnDelete = (_ctx: EventContext, row: DbNote) => {
|
||||
console.debug("server deleting", row.id);
|
||||
setNotes(notes().filter(({id}) => id !== row.id));
|
||||
};
|
||||
const onConnect = (connection: DbConnection, identity: Identity, token: string) => {
|
||||
console.debug("onConnect")
|
||||
const onConnect = (
|
||||
connection: DatabaseConnection,
|
||||
identity: Identity,
|
||||
token: string,
|
||||
) => {
|
||||
console.debug("onConnect");
|
||||
localStorage.setItem("auth_token", token);
|
||||
console.debug("Connected with Identity", identity.toHexString());
|
||||
|
||||
const note = connection.db.note;
|
||||
note.onInsert(noteOnInsert)
|
||||
note.onUpdate(noteOnUpdate)
|
||||
note.onDelete(noteOnDelete)
|
||||
note.onInsert(noteOnInsert);
|
||||
note.onUpdate(noteOnUpdate);
|
||||
note.onDelete(noteOnDelete);
|
||||
|
||||
setStatus(Status.Loading);
|
||||
connection.subscriptionBuilder().onApplied(() => {
|
||||
console.debug("onApplied", "SELECT * FROM note");
|
||||
setStatus(Status.Connected)
|
||||
})
|
||||
connection
|
||||
.subscriptionBuilder()
|
||||
.onApplied(() => {
|
||||
console.debug("onApplied", "SELECT * FROM note");
|
||||
setStatus(Status.Connected);
|
||||
})
|
||||
.onError(console.error)
|
||||
.subscribe("SELECT * FROM note");
|
||||
}
|
||||
};
|
||||
|
||||
const onDisconnect = (_ctx: ErrorContext, error?: Error) => {
|
||||
if (error)
|
||||
console.error("Disconnecting", error)
|
||||
else
|
||||
console.error("Disconnecting")
|
||||
setStatus(Status.Disconnected)
|
||||
const conn = connection();
|
||||
if (!conn) return;
|
||||
const note = conn.db.note;
|
||||
note.removeOnInsert(noteOnInsert);
|
||||
note.removeOnUpdate(noteOnUpdate);
|
||||
note.removeOnDelete(noteOnDelete);
|
||||
}
|
||||
|
||||
setConnection(DbConnection.builder()
|
||||
.withUri(`ws://${window.location.hostname}:3000`)
|
||||
.withModuleName("test")
|
||||
.withToken(localStorage.getItem("auth_token") ?? "")
|
||||
.onConnect(onConnect)
|
||||
.onDisconnect(onDisconnect)
|
||||
.onConnectError(console.error)
|
||||
.build())
|
||||
})
|
||||
setConnection(
|
||||
DatabaseConnection.builder()
|
||||
.withUri(`ws://${globalThis.location.hostname}:3000`)
|
||||
.withModuleName("test")
|
||||
.withToken(localStorage.getItem("auth_token") ?? "")
|
||||
.onConnect(onConnect)
|
||||
.onDisconnect(onDisconnect)
|
||||
.onConnectError(console.error)
|
||||
.build(),
|
||||
);
|
||||
});
|
||||
|
||||
// Not predicted because next ID is not easy to determine
|
||||
const tryAddNote = () => {
|
||||
connection()?.reducers.createNote();
|
||||
}
|
||||
};
|
||||
|
||||
const tryUpdateNote = (note: Note, value: string) => {
|
||||
connection()?.reducers.updateNote(note.id, value);
|
||||
// Predict!
|
||||
note.lastUpdate(Timestamp.now())
|
||||
}
|
||||
note.lastUpdate(Timestamp.now());
|
||||
};
|
||||
|
||||
const tryDeleteNote = (id: number) => {
|
||||
connection()?.reducers.deleteNote(id);
|
||||
console.debug("client deleting", id);
|
||||
// Predict!
|
||||
setNotes(notes().filter(({id: noteId}) => noteId !== id));
|
||||
}
|
||||
setNotes(notes().filter(({ id: noteId }) => noteId !== id));
|
||||
};
|
||||
|
||||
const getStatusText = () => {
|
||||
switch (status()) {
|
||||
case Status.Connecting:
|
||||
{
|
||||
return "connecting...";
|
||||
}
|
||||
case Status.Loading:
|
||||
{
|
||||
return "loading...";
|
||||
}
|
||||
case Status.Connected:
|
||||
{
|
||||
return "connected"
|
||||
}
|
||||
case Status.Disconnected:
|
||||
{
|
||||
return "disconnected";
|
||||
}
|
||||
default:
|
||||
{
|
||||
return "Huh?";
|
||||
}
|
||||
case Status.Connecting: {
|
||||
return "connecting...";
|
||||
}
|
||||
case Status.Loading: {
|
||||
return "loading...";
|
||||
}
|
||||
case Status.Connected: {
|
||||
return "connected";
|
||||
}
|
||||
case Status.Disconnected: {
|
||||
return "disconnected";
|
||||
}
|
||||
default: {
|
||||
return "Huh?";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Show when={status() === Status.Connected} fallback={<span>{getStatusText()}</span>}>
|
||||
<Show
|
||||
when={status() === Status.Connected}
|
||||
fallback={<span>{getStatusText()}</span>}>
|
||||
<button on:click={tryAddNote}>+</button>
|
||||
<br />
|
||||
<For each={notes()}>
|
||||
{
|
||||
(note) => {
|
||||
return <>
|
||||
<span attr:data-note-id={note.id} attr:data-last-updated={note.lastUpdate().toDate().toISOString()}>
|
||||
<textarea id={`note-${note.id}`} on:input={ev => tryUpdateNote(note, ev.target.value)} value={note.value()}></textarea>
|
||||
<button id={`delete-note-${note.id}`} on:click={_ => tryDeleteNote(note.id)}>-</button>
|
||||
{(note) => {
|
||||
return (
|
||||
<>
|
||||
<span
|
||||
attr:data-note-id={note.id}
|
||||
attr:data-last-updated={note
|
||||
.lastUpdate()
|
||||
.toDate()
|
||||
.toISOString()}>
|
||||
<textarea
|
||||
id={`note-${note.id}`}
|
||||
on:input={(event) => {
|
||||
tryUpdateNote(note, event.target.value);
|
||||
}}
|
||||
value={note.value()}
|
||||
/>
|
||||
<button
|
||||
id={`delete-note-${note.id}`}
|
||||
on:click={(_) => {
|
||||
tryDeleteNote(note.id);
|
||||
}}>
|
||||
-
|
||||
</button>
|
||||
</span>
|
||||
<br />
|
||||
</>
|
||||
}
|
||||
}
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</Show >
|
||||
)
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,12 +38,11 @@ export type CreateNote = {};
|
|||
*/
|
||||
export namespace CreateNote {
|
||||
/**
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
export function getTypeScriptAlgebraicType(): AlgebraicType {
|
||||
return AlgebraicType.createProductType([
|
||||
]);
|
||||
return AlgebraicType.createProductType([]);
|
||||
}
|
||||
|
||||
export function serialize(writer: BinaryWriter, value: CreateNote): void {
|
||||
|
@ -53,6 +52,4 @@ export namespace CreateNote {
|
|||
export function deserialize(reader: BinaryReader): CreateNote {
|
||||
return CreateNote.getTypeScriptAlgebraicType().deserialize(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import {
|
|||
} from "@clockworklabs/spacetimedb-sdk";
|
||||
|
||||
export type DeleteNote = {
|
||||
id: number,
|
||||
id: number;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,9 +40,9 @@ export type DeleteNote = {
|
|||
*/
|
||||
export namespace DeleteNote {
|
||||
/**
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
export function getTypeScriptAlgebraicType(): AlgebraicType {
|
||||
return AlgebraicType.createProductType([
|
||||
new ProductTypeElement("id", AlgebraicType.createU32Type()),
|
||||
|
@ -56,6 +56,4 @@ export namespace DeleteNote {
|
|||
export function deserialize(reader: BinaryReader): DeleteNote {
|
||||
return DeleteNote.getTypeScriptAlgebraicType().deserialize(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -79,32 +79,42 @@ const REMOTE_MODULE = {
|
|||
eventContextConstructor: (imp: DbConnectionImpl, event: Event<Reducer>) => {
|
||||
return {
|
||||
...(imp as DbConnection),
|
||||
event
|
||||
}
|
||||
event,
|
||||
};
|
||||
},
|
||||
dbViewConstructor: (imp: DbConnectionImpl) => {
|
||||
return new RemoteTables(imp);
|
||||
},
|
||||
reducersConstructor: (imp: DbConnectionImpl, setReducerFlags: SetReducerFlags) => {
|
||||
reducersConstructor: (
|
||||
imp: DbConnectionImpl,
|
||||
setReducerFlags: SetReducerFlags,
|
||||
) => {
|
||||
return new RemoteReducers(imp, setReducerFlags);
|
||||
},
|
||||
setReducerFlagsConstructor: () => {
|
||||
return new SetReducerFlags();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// A type representing all the possible variants of a reducer.
|
||||
export type Reducer = never
|
||||
| { name: "CreateNote", args: CreateNote }
|
||||
| { name: "DeleteNote", args: DeleteNote }
|
||||
| { name: "UpdateNote", args: UpdateNote }
|
||||
;
|
||||
export type Reducer =
|
||||
| never
|
||||
| { name: "CreateNote"; args: CreateNote }
|
||||
| { name: "DeleteNote"; args: DeleteNote }
|
||||
| { name: "UpdateNote"; args: UpdateNote };
|
||||
|
||||
export class RemoteReducers {
|
||||
constructor(private connection: DbConnectionImpl, private setCallReducerFlags: SetReducerFlags) {}
|
||||
constructor(
|
||||
private connection: DbConnectionImpl,
|
||||
private setCallReducerFlags: SetReducerFlags,
|
||||
) {}
|
||||
|
||||
createNote() {
|
||||
this.connection.callReducer("create_note", new Uint8Array(0), this.setCallReducerFlags.createNoteFlags);
|
||||
this.connection.callReducer(
|
||||
"create_note",
|
||||
new Uint8Array(0),
|
||||
this.setCallReducerFlags.createNoteFlags,
|
||||
);
|
||||
}
|
||||
|
||||
onCreateNote(callback: (ctx: ReducerEventContext) => void) {
|
||||
|
@ -120,7 +130,11 @@ export class RemoteReducers {
|
|||
let __writer = new BinaryWriter(1024);
|
||||
DeleteNote.getTypeScriptAlgebraicType().serialize(__writer, __args);
|
||||
let __argsBuffer = __writer.getBuffer();
|
||||
this.connection.callReducer("delete_note", __argsBuffer, this.setCallReducerFlags.deleteNoteFlags);
|
||||
this.connection.callReducer(
|
||||
"delete_note",
|
||||
__argsBuffer,
|
||||
this.setCallReducerFlags.deleteNoteFlags,
|
||||
);
|
||||
}
|
||||
|
||||
onDeleteNote(callback: (ctx: ReducerEventContext, id: number) => void) {
|
||||
|
@ -136,57 +150,101 @@ export class RemoteReducers {
|
|||
let __writer = new BinaryWriter(1024);
|
||||
UpdateNote.getTypeScriptAlgebraicType().serialize(__writer, __args);
|
||||
let __argsBuffer = __writer.getBuffer();
|
||||
this.connection.callReducer("update_note", __argsBuffer, this.setCallReducerFlags.updateNoteFlags);
|
||||
this.connection.callReducer(
|
||||
"update_note",
|
||||
__argsBuffer,
|
||||
this.setCallReducerFlags.updateNoteFlags,
|
||||
);
|
||||
}
|
||||
|
||||
onUpdateNote(callback: (ctx: ReducerEventContext, id: number, value: string) => void) {
|
||||
onUpdateNote(
|
||||
callback: (ctx: ReducerEventContext, id: number, value: string) => void,
|
||||
) {
|
||||
this.connection.onReducer("update_note", callback);
|
||||
}
|
||||
|
||||
removeOnUpdateNote(callback: (ctx: ReducerEventContext, id: number, value: string) => void) {
|
||||
removeOnUpdateNote(
|
||||
callback: (ctx: ReducerEventContext, id: number, value: string) => void,
|
||||
) {
|
||||
this.connection.offReducer("update_note", callback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class SetReducerFlags {
|
||||
createNoteFlags: CallReducerFlags = 'FullUpdate';
|
||||
createNoteFlags: CallReducerFlags = "FullUpdate";
|
||||
createNote(flags: CallReducerFlags) {
|
||||
this.createNoteFlags = flags;
|
||||
}
|
||||
|
||||
deleteNoteFlags: CallReducerFlags = 'FullUpdate';
|
||||
deleteNoteFlags: CallReducerFlags = "FullUpdate";
|
||||
deleteNote(flags: CallReducerFlags) {
|
||||
this.deleteNoteFlags = flags;
|
||||
}
|
||||
|
||||
updateNoteFlags: CallReducerFlags = 'FullUpdate';
|
||||
updateNoteFlags: CallReducerFlags = "FullUpdate";
|
||||
updateNote(flags: CallReducerFlags) {
|
||||
this.updateNoteFlags = flags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class RemoteTables {
|
||||
constructor(private connection: DbConnectionImpl) {}
|
||||
|
||||
get note(): NoteTableHandle {
|
||||
return new NoteTableHandle(this.connection.clientCache.getOrCreateTable<Note>(REMOTE_MODULE.tables.note));
|
||||
return new NoteTableHandle(
|
||||
this.connection.clientCache.getOrCreateTable<Note>(
|
||||
REMOTE_MODULE.tables.note,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionBuilder extends SubscriptionBuilderImpl<RemoteTables, RemoteReducers, SetReducerFlags> { }
|
||||
export class SubscriptionBuilder extends SubscriptionBuilderImpl<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags
|
||||
> {}
|
||||
|
||||
export class DbConnection extends DbConnectionImpl<RemoteTables, RemoteReducers, SetReducerFlags> {
|
||||
static builder = (): DbConnectionBuilder<DbConnection, ErrorContext, SubscriptionEventContext> => {
|
||||
return new DbConnectionBuilder<DbConnection, ErrorContext, SubscriptionEventContext>(REMOTE_MODULE, (imp: DbConnectionImpl) => imp as DbConnection);
|
||||
}
|
||||
export class DbConnection extends DbConnectionImpl<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags
|
||||
> {
|
||||
static builder = (): DbConnectionBuilder<
|
||||
DbConnection,
|
||||
ErrorContext,
|
||||
SubscriptionEventContext
|
||||
> => {
|
||||
return new DbConnectionBuilder<
|
||||
DbConnection,
|
||||
ErrorContext,
|
||||
SubscriptionEventContext
|
||||
>(REMOTE_MODULE, (imp: DbConnectionImpl) => imp as DbConnection);
|
||||
};
|
||||
subscriptionBuilder = (): SubscriptionBuilder => {
|
||||
return new SubscriptionBuilder(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export type EventContext = EventContextInterface<RemoteTables, RemoteReducers, SetReducerFlags, Reducer>;
|
||||
export type ReducerEventContext = ReducerEventContextInterface<RemoteTables, RemoteReducers, SetReducerFlags, Reducer>;
|
||||
export type SubscriptionEventContext = SubscriptionEventContextInterface<RemoteTables, RemoteReducers, SetReducerFlags>;
|
||||
export type ErrorContext = ErrorContextInterface<RemoteTables, RemoteReducers, SetReducerFlags>;
|
||||
export type EventContext = EventContextInterface<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags,
|
||||
Reducer
|
||||
>;
|
||||
export type ReducerEventContext = ReducerEventContextInterface<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags,
|
||||
Reducer
|
||||
>;
|
||||
export type SubscriptionEventContext = SubscriptionEventContextInterface<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags
|
||||
>;
|
||||
export type ErrorContext = ErrorContextInterface<
|
||||
RemoteTables,
|
||||
RemoteReducers,
|
||||
SetReducerFlags
|
||||
>;
|
||||
|
|
|
@ -82,25 +82,28 @@ export class NoteTableHandle {
|
|||
|
||||
onInsert = (cb: (ctx: EventContext, row: Note) => void) => {
|
||||
return this.tableCache.onInsert(cb);
|
||||
}
|
||||
};
|
||||
|
||||
removeOnInsert = (cb: (ctx: EventContext, row: Note) => void) => {
|
||||
return this.tableCache.removeOnInsert(cb);
|
||||
}
|
||||
};
|
||||
|
||||
onDelete = (cb: (ctx: EventContext, row: Note) => void) => {
|
||||
return this.tableCache.onDelete(cb);
|
||||
}
|
||||
};
|
||||
|
||||
removeOnDelete = (cb: (ctx: EventContext, row: Note) => void) => {
|
||||
return this.tableCache.removeOnDelete(cb);
|
||||
}
|
||||
};
|
||||
|
||||
// Updates are only defined for tables with primary keys.
|
||||
onUpdate = (cb: (ctx: EventContext, oldRow: Note, newRow: Note) => void) => {
|
||||
return this.tableCache.onUpdate(cb);
|
||||
}
|
||||
};
|
||||
|
||||
removeOnUpdate = (cb: (ctx: EventContext, onRow: Note, newRow: Note) => void) => {
|
||||
removeOnUpdate = (
|
||||
cb: (ctx: EventContext, onRow: Note, newRow: Note) => void,
|
||||
) => {
|
||||
return this.tableCache.removeOnUpdate(cb);
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ import {
|
|||
deepEqual,
|
||||
} from "@clockworklabs/spacetimedb-sdk";
|
||||
export type Note = {
|
||||
id: number,
|
||||
lastUpdate: Timestamp,
|
||||
value: string,
|
||||
id: number;
|
||||
lastUpdate: Timestamp;
|
||||
value: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,9 @@ export type Note = {
|
|||
*/
|
||||
export namespace Note {
|
||||
/**
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
export function getTypeScriptAlgebraicType(): AlgebraicType {
|
||||
return AlgebraicType.createProductType([
|
||||
new ProductTypeElement("id", AlgebraicType.createU32Type()),
|
||||
|
@ -59,7 +59,4 @@ export namespace Note {
|
|||
export function deserialize(reader: BinaryReader): Note {
|
||||
return Note.getTypeScriptAlgebraicType().deserialize(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ import {
|
|||
} from "@clockworklabs/spacetimedb-sdk";
|
||||
|
||||
export type UpdateNote = {
|
||||
id: number,
|
||||
value: string,
|
||||
id: number;
|
||||
value: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,9 @@ export type UpdateNote = {
|
|||
*/
|
||||
export namespace UpdateNote {
|
||||
/**
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
* A function which returns this type represented as an AlgebraicType.
|
||||
* This function is derived from the AlgebraicType used to generate this type.
|
||||
*/
|
||||
export function getTypeScriptAlgebraicType(): AlgebraicType {
|
||||
return AlgebraicType.createProductType([
|
||||
new ProductTypeElement("id", AlgebraicType.createU32Type()),
|
||||
|
@ -58,6 +58,4 @@ export namespace UpdateNote {
|
|||
export function deserialize(reader: BinaryReader): UpdateNote {
|
||||
return UpdateNote.getTypeScriptAlgebraicType().deserialize(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -41,4 +41,4 @@ button:hover {
|
|||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* @refresh reload */
|
||||
import './index.css'
|
||||
import App from './app.tsx'
|
||||
import { render } from 'solid-js/web'
|
||||
import "./index.css";
|
||||
import App from "./app.tsx";
|
||||
import { render } from "solid-js/web";
|
||||
|
||||
const root = document.querySelector('#root')
|
||||
const root = document.querySelector("#root");
|
||||
|
||||
render(() => <App />, root!)
|
||||
render(() => <App />, root!);
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import { type Signal, createSignal } from "solid-js"
|
||||
import type { Note as DbNote } from "./bindings"
|
||||
import type { Timestamp } from "@clockworklabs/spacetimedb-sdk"
|
||||
|
||||
export class Note {
|
||||
#valueSignal: Signal<ValueType>
|
||||
#lastUpdatedSignal: Signal<Timestamp>
|
||||
id: number
|
||||
#getValue(): ValueType {
|
||||
return this.#valueSignal[0]()
|
||||
}
|
||||
#setValue(value: ValueType): ValueType {
|
||||
return this.#valueSignal[1](value)
|
||||
}
|
||||
value(value?: ValueType): ValueType {
|
||||
if (value === undefined) {
|
||||
return this.#getValue();
|
||||
}
|
||||
return this.#setValue(value);
|
||||
}
|
||||
|
||||
#getLastUpdate(): Timestamp {
|
||||
return this.#lastUpdatedSignal[0]();
|
||||
}
|
||||
#setLastUpdate(lastUpdate: Timestamp): Timestamp {
|
||||
return this.#lastUpdatedSignal[1](lastUpdate);
|
||||
}
|
||||
lastUpdate(lastUpdate?: Timestamp): Timestamp {
|
||||
if (lastUpdate === undefined) {
|
||||
return this.#getLastUpdate();
|
||||
}
|
||||
return this.#setLastUpdate(lastUpdate);
|
||||
}
|
||||
|
||||
update(dbNote: DbNote) {
|
||||
this.#setValue(dbNote.value);
|
||||
this.#setLastUpdate(dbNote.lastUpdate);
|
||||
}
|
||||
|
||||
constructor(dbNote: DbNote) {
|
||||
console.debug(dbNote, dbNote.lastUpdate.toDate().toISOString())
|
||||
this.id = dbNote.id;
|
||||
this.#valueSignal = createSignal(dbNote.value);
|
||||
this.#lastUpdatedSignal = createSignal(dbNote.lastUpdate);
|
||||
}
|
||||
}
|
47
client/src/library.ts
Normal file
47
client/src/library.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { type Signal, createSignal } from "solid-js";
|
||||
import type { Note as DatabaseNote } from "./bindings";
|
||||
import type { Timestamp } from "@clockworklabs/spacetimedb-sdk";
|
||||
|
||||
type ValueType = string;
|
||||
export class Note {
|
||||
#valueSignal: Signal<ValueType>;
|
||||
#lastUpdatedSignal: Signal<Timestamp>;
|
||||
id: number;
|
||||
#getValue(): ValueType {
|
||||
return this.#valueSignal[0]();
|
||||
}
|
||||
#setValue(value: ValueType): ValueType {
|
||||
return this.#valueSignal[1](value);
|
||||
}
|
||||
value(value?: ValueType): ValueType {
|
||||
if (value === undefined) {
|
||||
return this.#getValue();
|
||||
}
|
||||
return this.#setValue(value);
|
||||
}
|
||||
|
||||
#getLastUpdate(): Timestamp {
|
||||
return this.#lastUpdatedSignal[0]();
|
||||
}
|
||||
#setLastUpdate(lastUpdate: Timestamp): Timestamp {
|
||||
return this.#lastUpdatedSignal[1](lastUpdate);
|
||||
}
|
||||
lastUpdate(lastUpdate?: Timestamp): Timestamp {
|
||||
if (lastUpdate === undefined) {
|
||||
return this.#getLastUpdate();
|
||||
}
|
||||
return this.#setLastUpdate(lastUpdate);
|
||||
}
|
||||
|
||||
update(databaseNote: DatabaseNote) {
|
||||
this.#setValue(databaseNote.value);
|
||||
this.#setLastUpdate(databaseNote.lastUpdate);
|
||||
}
|
||||
|
||||
constructor(databaseNote: DatabaseNote) {
|
||||
console.debug(databaseNote, databaseNote.lastUpdate.toDate().toISOString());
|
||||
this.id = databaseNote.id;
|
||||
this.#valueSignal = createSignal(databaseNote.value);
|
||||
this.#lastUpdatedSignal = createSignal(databaseNote.lastUpdate);
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
|
@ -1,7 +1,25 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"skipLibCheck": true,
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js",
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import oxlint from 'vite-plugin-oxlint'
|
||||
import solid from 'vite-plugin-solid'
|
||||
import { defineConfig } from "vite";
|
||||
import oxlint from "vite-plugin-oxlint";
|
||||
import solid from "vite-plugin-solid";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [solid(), oxlint()],
|
||||
})
|
||||
export default defineConfig({ plugins: [solid(), oxlint()] });
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
pnpm
|
||||
nodejs
|
||||
oxlint
|
||||
eslint
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue