@veams/status-quo 1.5.1 → 1.7.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.
Files changed (127) hide show
  1. package/.turbo/turbo-build.log +12 -0
  2. package/.turbo/turbo-check$colon$types.log +4 -0
  3. package/.turbo/turbo-docs$colon$build.log +14 -0
  4. package/.turbo/turbo-lint.log +8 -0
  5. package/.turbo/turbo-test.log +15 -0
  6. package/CHANGELOG.md +24 -3
  7. package/README.md +217 -41
  8. package/dist/config/status-quo-config.d.ts +13 -0
  9. package/dist/config/status-quo-config.js +14 -0
  10. package/dist/config/status-quo-config.js.map +1 -1
  11. package/dist/hooks/__tests__/state-provider.spec.d.ts +4 -0
  12. package/dist/hooks/__tests__/state-provider.spec.js +179 -0
  13. package/dist/hooks/__tests__/state-provider.spec.js.map +1 -0
  14. package/dist/hooks/__tests__/state-selector.spec.js +11 -12
  15. package/dist/hooks/__tests__/state-selector.spec.js.map +1 -1
  16. package/dist/hooks/__tests__/state-singleton.spec.js +10 -11
  17. package/dist/hooks/__tests__/state-singleton.spec.js.map +1 -1
  18. package/dist/hooks/index.d.ts +1 -0
  19. package/dist/hooks/index.js +1 -0
  20. package/dist/hooks/index.js.map +1 -1
  21. package/dist/hooks/state-factory.js.map +1 -1
  22. package/dist/hooks/state-provider.d.ts +14 -0
  23. package/dist/hooks/state-provider.js +24 -0
  24. package/dist/hooks/state-provider.js.map +1 -0
  25. package/dist/hooks/state-subscription-selector.js +6 -2
  26. package/dist/hooks/state-subscription-selector.js.map +1 -1
  27. package/dist/hooks/state-subscription.js +1 -1
  28. package/dist/hooks/state-subscription.js.map +1 -1
  29. package/dist/index.d.ts +4 -5
  30. package/dist/index.js +2 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/react/hooks/__tests__/state-provider.spec.d.ts +4 -0
  33. package/dist/react/hooks/__tests__/state-provider.spec.js +179 -0
  34. package/dist/react/hooks/__tests__/state-provider.spec.js.map +1 -0
  35. package/dist/react/hooks/__tests__/state-selector.spec.d.ts +4 -0
  36. package/dist/react/hooks/__tests__/state-selector.spec.js +547 -0
  37. package/dist/react/hooks/__tests__/state-selector.spec.js.map +1 -0
  38. package/dist/react/hooks/__tests__/state-singleton.spec.d.ts +4 -0
  39. package/dist/react/hooks/__tests__/state-singleton.spec.js +96 -0
  40. package/dist/react/hooks/__tests__/state-singleton.spec.js.map +1 -0
  41. package/{src/hooks/index.ts → dist/react/hooks/index.d.ts} +1 -0
  42. package/dist/react/hooks/index.js +7 -0
  43. package/dist/react/hooks/index.js.map +1 -0
  44. package/dist/react/hooks/state-actions.d.ts +2 -0
  45. package/dist/react/hooks/state-actions.js +5 -0
  46. package/dist/react/hooks/state-actions.js.map +1 -0
  47. package/dist/react/hooks/state-factory.d.ts +7 -0
  48. package/dist/react/hooks/state-factory.js +13 -0
  49. package/dist/react/hooks/state-factory.js.map +1 -0
  50. package/dist/react/hooks/state-handler.d.ts +2 -0
  51. package/dist/react/hooks/state-handler.js +9 -0
  52. package/dist/react/hooks/state-handler.js.map +1 -0
  53. package/dist/react/hooks/state-provider.d.ts +14 -0
  54. package/dist/react/hooks/state-provider.js +24 -0
  55. package/dist/react/hooks/state-provider.js.map +1 -0
  56. package/dist/react/hooks/state-singleton.d.ts +6 -0
  57. package/dist/react/hooks/state-singleton.js +7 -0
  58. package/dist/react/hooks/state-singleton.js.map +1 -0
  59. package/dist/react/hooks/state-subscription-selector.d.ts +3 -0
  60. package/dist/react/hooks/state-subscription-selector.js +114 -0
  61. package/dist/react/hooks/state-subscription-selector.js.map +1 -0
  62. package/dist/react/hooks/state-subscription.d.ts +9 -0
  63. package/dist/react/hooks/state-subscription.js +53 -0
  64. package/dist/react/hooks/state-subscription.js.map +1 -0
  65. package/dist/react/index.d.ts +1 -0
  66. package/dist/react/index.js +2 -0
  67. package/dist/react/index.js.map +1 -0
  68. package/dist/store/__tests__/observable-state-handler.spec.js +66 -11
  69. package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -1
  70. package/dist/store/__tests__/signal-state-handler.spec.js.map +1 -1
  71. package/dist/store/base-state-handler.d.ts +3 -5
  72. package/dist/store/base-state-handler.js +10 -9
  73. package/dist/store/base-state-handler.js.map +1 -1
  74. package/dist/store/dev-tools.js +0 -3
  75. package/dist/store/dev-tools.js.map +1 -1
  76. package/dist/store/observable-state-handler.d.ts +4 -10
  77. package/dist/store/observable-state-handler.js +4 -11
  78. package/dist/store/observable-state-handler.js.map +1 -1
  79. package/dist/store/signal-state-handler.d.ts +2 -5
  80. package/dist/store/signal-state-handler.js +3 -2
  81. package/dist/store/signal-state-handler.js.map +1 -1
  82. package/dist/store/state-singleton.js +1 -1
  83. package/dist/store/state-singleton.js.map +1 -1
  84. package/eslint.config.mjs +75 -0
  85. package/package.json +18 -18
  86. package/src/config/status-quo-config.ts +31 -1
  87. package/src/index.ts +11 -15
  88. package/src/react/hooks/__tests__/state-provider.spec.tsx +286 -0
  89. package/src/{hooks → react/hooks}/__tests__/state-selector.spec.tsx +118 -44
  90. package/src/{hooks → react/hooks}/__tests__/state-singleton.spec.tsx +21 -20
  91. package/src/react/hooks/index.ts +11 -0
  92. package/src/{hooks → react/hooks}/state-actions.tsx +1 -1
  93. package/src/{hooks → react/hooks}/state-factory.tsx +2 -2
  94. package/src/{hooks → react/hooks}/state-handler.tsx +1 -1
  95. package/src/react/hooks/state-provider.tsx +56 -0
  96. package/src/{hooks → react/hooks}/state-singleton.tsx +1 -1
  97. package/src/react/hooks/state-subscription-selector.tsx +190 -0
  98. package/src/{hooks → react/hooks}/state-subscription.tsx +5 -9
  99. package/src/react/index.ts +1 -0
  100. package/src/store/__tests__/observable-state-handler.spec.ts +92 -13
  101. package/src/store/__tests__/signal-state-handler.spec.ts +5 -1
  102. package/src/store/base-state-handler.ts +17 -22
  103. package/src/store/dev-tools.ts +3 -3
  104. package/src/store/observable-state-handler.ts +12 -22
  105. package/src/store/signal-state-handler.ts +11 -8
  106. package/src/store/state-singleton.ts +1 -1
  107. package/tsconfig.json +2 -3
  108. package/.eslintrc.cjs +0 -132
  109. package/.github/workflows/pages.yml +0 -46
  110. package/.github/workflows/release.yml +0 -33
  111. package/.nvmrc +0 -1
  112. package/.prettierrc +0 -7
  113. package/docs/assets/index-BBmpszOW.css +0 -1
  114. package/docs/assets/index-Cf8El_RO.js +0 -194
  115. package/docs/assets/statusquo-logo-8GVRbxpc.png +0 -0
  116. package/docs/index.html +0 -13
  117. package/playground/index.html +0 -12
  118. package/playground/src/App.tsx +0 -699
  119. package/playground/src/assets/philosophy-agnostic.svg +0 -18
  120. package/playground/src/assets/philosophy-separation.svg +0 -13
  121. package/playground/src/assets/philosophy-swap.svg +0 -17
  122. package/playground/src/assets/statusquo-logo.png +0 -0
  123. package/playground/src/main.tsx +0 -19
  124. package/playground/src/styles.css +0 -534
  125. package/playground/tsconfig.json +0 -12
  126. package/playground/vite.config.ts +0 -18
  127. package/src/hooks/state-subscription-selector.tsx +0 -111
@@ -1,22 +1,17 @@
1
- import { withDevTools } from './dev-tools.js';
1
+ import { resolveDevToolsOptions } from '../config/status-quo-config.js';
2
2
  import { createSelectorCache, selectWithCache } from '../utils/selector-cache.js';
3
+ import { withDevTools } from './dev-tools.js';
3
4
 
4
5
  import type { StateSubscriptionHandler } from '../types/types.js';
5
- import type { DevTools, MessagePayload } from './dev-tools.js';
6
6
  import type { EqualityFn, Selector } from '../utils/selector-cache.js';
7
-
8
- type DevToolsOptions = {
9
- enabled?: boolean;
10
- namespace: string;
11
- };
7
+ import type { DevTools, MessagePayload } from './dev-tools.js';
8
+ import type { DevToolsOptions } from '../config/status-quo-config.js';
12
9
 
13
10
  type Subscribable<T> = {
14
11
  subscribe: (listener: (value: T) => void) => () => void;
15
12
  getSnapshot?: () => T;
16
13
  };
17
14
 
18
- const defaultDevToolsOptions = { enabled: false, namespace: 'Store' };
19
-
20
15
  const devToolsFeatures = {
21
16
  pause: true,
22
17
  lock: true,
@@ -41,19 +36,18 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
41
36
  }
42
37
 
43
38
  protected initDevTools(devToolsOptions?: DevToolsOptions) {
44
- const mergedOptions = {
45
- ...defaultDevToolsOptions,
46
- ...devToolsOptions,
47
- };
39
+ const resolvedOptions = resolveDevToolsOptions(devToolsOptions);
48
40
 
49
- if (!mergedOptions.enabled) {
41
+ if (!resolvedOptions.enabled) {
50
42
  this.devTools = null;
51
43
  return;
52
44
  }
53
45
 
46
+ const namespace = devToolsOptions?.namespace ?? this.getDevToolsNamespace();
47
+
54
48
  this.devTools = withDevTools(this.initialState, {
55
- name: mergedOptions.namespace,
56
- instanceId: mergedOptions.namespace.toLowerCase().replaceAll(' ', '-'),
49
+ name: namespace,
50
+ instanceId: namespace.toLowerCase().replaceAll(' ', '-'),
57
51
  actionCreators: this.getActions(),
58
52
  features: devToolsFeatures,
59
53
  });
@@ -86,23 +80,24 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
86
80
  protected abstract getStateValue(): S;
87
81
  protected abstract setStateValue(nextState: S): void;
88
82
 
83
+ protected getDevToolsNamespace() {
84
+ return this.constructor.name || 'Store';
85
+ }
86
+
89
87
  protected bindSubscribable<T, Sel>(
90
88
  service: Subscribable<T>,
91
89
  onChange: (value: Sel) => void,
92
90
  selector: Selector<T, Sel>,
93
91
  isEqual?: EqualityFn<Sel>
94
92
  ): void;
95
- protected bindSubscribable<T>(
96
- service: Subscribable<T>,
97
- onChange: (value: T) => void
98
- ): void;
93
+ protected bindSubscribable<T>(service: Subscribable<T>, onChange: (value: T) => void): void;
99
94
  protected bindSubscribable<T, Sel = T>(
100
95
  service: Subscribable<T>,
101
96
  onChange: (value: Sel) => void,
102
97
  selector?: Selector<T, Sel>,
103
98
  isEqual: EqualityFn<Sel> = Object.is
104
99
  ) {
105
- const selectorFn = (selector ?? ((value: T) => value as unknown as Sel)) as Selector<T, Sel>;
100
+ const selectorFn = (selector ?? ((value: T) => value as unknown as Sel));
106
101
  const selectorCache = createSelectorCache<Sel>();
107
102
  let receivedSyncValue = false;
108
103
 
@@ -150,7 +145,7 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
150
145
 
151
146
  case 'JUMP_TO_STATE':
152
147
  case 'JUMP_TO_ACTION':
153
- this.setStateValue(JSON.parse(message.state));
148
+ this.setStateValue(JSON.parse(message.state) as S);
154
149
  break;
155
150
 
156
151
  default:
@@ -28,17 +28,17 @@ export function withDevTools<S>(initialState: S, options = {}): DevTools | null
28
28
  return null;
29
29
  }
30
30
 
31
- // eslint-disable-next-line no-underscore-dangle
31
+
32
32
  if (!window.__REDUX_DEVTOOLS_EXTENSION__) {
33
33
  console.error('Status Quo :: Devtools Extension is not installed!');
34
34
  return null;
35
35
  }
36
36
 
37
- // eslint-disable-next-line no-underscore-dangle
37
+
38
38
  const devTools = window.__REDUX_DEVTOOLS_EXTENSION__.connect(options);
39
39
 
40
40
  devTools.init(initialState);
41
41
 
42
- // eslint-disable-next-line consistent-return
42
+
43
43
  return devTools;
44
44
  }
@@ -1,18 +1,15 @@
1
1
  import { BehaviorSubject, distinctUntilChanged, distinctUntilKeyChanged, map } from 'rxjs';
2
2
 
3
- import { BaseStateHandler } from './base-state-handler.js';
4
3
  import { resolveDistinctOptions } from '../config/status-quo-config.js';
4
+ import { BaseStateHandler } from './base-state-handler.js';
5
5
 
6
+ import type { DevToolsOptions, DistinctOptions } from '../config/status-quo-config.js';
6
7
  import type { Observable } from 'rxjs';
7
- import type { DistinctOptions } from '../config/status-quo-config.js';
8
8
 
9
9
  type ObservableStateHandlerProps<S> = {
10
10
  initialState: S;
11
11
  options?: {
12
- devTools?: {
13
- enabled?: boolean;
14
- namespace: string;
15
- };
12
+ devTools?: DevToolsOptions;
16
13
  distinct?: DistinctOptions<S>;
17
14
  useDistinctUntilChanged?: boolean;
18
15
  };
@@ -27,7 +24,10 @@ export abstract class ObservableStateHandler<S, A> extends BaseStateHandler<S, A
27
24
  protected constructor({ initialState, options }: ObservableStateHandlerProps<S>) {
28
25
  super(initialState);
29
26
  this.state$ = new BehaviorSubject<S>(initialState);
30
- this.distinctOptions = resolveDistinctOptions(options?.distinct, options?.useDistinctUntilChanged);
27
+ this.distinctOptions = resolveDistinctOptions(
28
+ options?.distinct,
29
+ options?.useDistinctUntilChanged
30
+ );
31
31
  this.initDevTools(options?.devTools);
32
32
  }
33
33
 
@@ -39,16 +39,15 @@ export abstract class ObservableStateHandler<S, A> extends BaseStateHandler<S, A
39
39
  this.state$.next(nextState);
40
40
  }
41
41
 
42
- getStateItemAsObservable(key: keyof S) {
42
+ getObservableItem<K extends keyof S>(key: K): Observable<S[K]> {
43
43
  return this.state$.pipe(
44
44
  distinctUntilKeyChanged(key),
45
45
  map((state) => state[key])
46
46
  );
47
47
  }
48
48
 
49
- getStateAsObservable(options: StateObservableOptions = {}) {
50
- const useDistinctUntilChanged =
51
- options.useDistinctUntilChanged ?? this.distinctOptions.enabled;
49
+ getObservable(options: StateObservableOptions = {}): Observable<S> {
50
+ const useDistinctUntilChanged = options.useDistinctUntilChanged ?? this.distinctOptions.enabled;
52
51
 
53
52
  if (!useDistinctUntilChanged) {
54
53
  return this.state$;
@@ -58,22 +57,13 @@ export abstract class ObservableStateHandler<S, A> extends BaseStateHandler<S, A
58
57
  distinctUntilChanged((previous, next) => {
59
58
  return this.distinctOptions.comparator(previous, next);
60
59
  })
61
- ) as Observable<S>;
62
- }
63
-
64
- getObservable(key: keyof S) {
65
- return this.getStateItemAsObservable(key);
66
- }
67
-
68
- /** @deprecated Use getObservable instead. */
69
- getObservableItem(key: keyof S) {
70
- return this.getObservable(key);
60
+ );
71
61
  }
72
62
 
73
63
  subscribe(listener: () => void): () => void;
74
64
  subscribe(listener: (value: S) => void): () => void;
75
65
  subscribe(listener: (value: S) => void) {
76
- const subscription = this.getStateAsObservable().subscribe((nextState) => {
66
+ const subscription = this.getObservable().subscribe((nextState) => {
77
67
  listener(nextState);
78
68
  });
79
69
  return () => subscription.unsubscribe();
@@ -1,18 +1,15 @@
1
1
  import { signal } from '@preact/signals-core';
2
2
 
3
- import { BaseStateHandler } from './base-state-handler.js';
4
3
  import { resolveDistinctOptions } from '../config/status-quo-config.js';
4
+ import { BaseStateHandler } from './base-state-handler.js';
5
5
 
6
+ import type { DevToolsOptions, DistinctOptions } from '../config/status-quo-config.js';
6
7
  import type { Signal } from '@preact/signals-core';
7
- import type { DistinctOptions } from '../config/status-quo-config.js';
8
8
 
9
9
  type SignalStateHandlerProps<S> = {
10
10
  initialState: S;
11
11
  options?: {
12
- devTools?: {
13
- enabled?: boolean;
14
- namespace: string;
15
- };
12
+ devTools?: DevToolsOptions;
16
13
  distinct?: DistinctOptions<S>;
17
14
  useDistinctUntilChanged?: boolean;
18
15
  };
@@ -26,7 +23,10 @@ export abstract class SignalStateHandler<S, A> extends BaseStateHandler<S, A> {
26
23
  super(initialState);
27
24
 
28
25
  this.state = signal<S>(initialState);
29
- this.distinctOptions = resolveDistinctOptions(options?.distinct, options?.useDistinctUntilChanged);
26
+ this.distinctOptions = resolveDistinctOptions(
27
+ options?.distinct,
28
+ options?.useDistinctUntilChanged
29
+ );
30
30
  this.initDevTools(options?.devTools);
31
31
  }
32
32
 
@@ -48,7 +48,10 @@ export abstract class SignalStateHandler<S, A> extends BaseStateHandler<S, A> {
48
48
  return;
49
49
  }
50
50
 
51
- if (this.distinctOptions.enabled && this.distinctOptions.comparator(previousSnapshot, nextState)) {
51
+ if (
52
+ this.distinctOptions.enabled &&
53
+ this.distinctOptions.comparator(previousSnapshot, nextState)
54
+ ) {
52
55
  previousSnapshot = nextState;
53
56
  return;
54
57
  }
@@ -10,7 +10,7 @@ export interface StateSingletonOptions {
10
10
 
11
11
  export function makeStateSingleton<S, A>(
12
12
  stateHandlerFactory: () => StateSubscriptionHandler<S, A>,
13
- { destroyOnNoConsumers = true }: StateSingletonOptions = {}
13
+ { destroyOnNoConsumers = false }: StateSingletonOptions = {}
14
14
  ): StateSingleton<S, A> {
15
15
  let instance: StateSubscriptionHandler<S, A> | null = null;
16
16
  const singleton: StateSingleton<S, A> & {
package/tsconfig.json CHANGED
@@ -24,9 +24,8 @@
24
24
  "declarationDir": "dist",
25
25
  "outDir": "dist",
26
26
  "typeRoots": [
27
- "node",
28
- "node_modules/@types",
29
- "node_modules/@redux-devtools/extension"
27
+ "../../node_modules/@types",
28
+ "../../node_modules/@redux-devtools/extension"
30
29
  ],
31
30
  "jsx": "react"
32
31
  },
package/.eslintrc.cjs DELETED
@@ -1,132 +0,0 @@
1
- module.exports = {
2
- root: true,
3
- parser: '@typescript-eslint/parser', // Specifies the ESLint parser
4
- plugins: ['react', '@typescript-eslint', 'simple-import-sort'],
5
- ignorePatterns: [
6
- '.eslintrc.js',
7
- '*.config.js',
8
- 'setupTests.js',
9
- 'setupTests.ts',
10
- 'env.js',
11
- 'env.local.js',
12
- ],
13
- extends: [
14
- 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
15
- 'airbnb-base',
16
- 'airbnb-typescript/base',
17
- 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
18
- 'plugin:react/recommended',
19
- 'airbnb',
20
- 'airbnb/hooks',
21
- 'airbnb-typescript',
22
- // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors.
23
- // Make sure this is always the last configuration in the extends array.
24
- 'plugin:prettier/recommended',
25
- ],
26
- parserOptions: {
27
- project: './tsconfig.json',
28
- ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
29
- sourceType: 'module', // Allows for the use of imports
30
- ecmaFeatures: {
31
- jsx: true, // Allows for the parsing of JSX
32
- },
33
- },
34
- settings: {
35
- react: {
36
- version: 'detect', // React version. "detect" automatically picks the version you have installed.
37
- },
38
- },
39
- // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
40
- rules: {
41
- 'max-classes-per-file': ['error', 2],
42
- 'no-console': 'off',
43
- '@typescript-eslint/consistent-type-imports': 'error',
44
- 'no-param-reassign': ['error', {props: false}], // for reducer and simple reference changes
45
- 'import/order': 'off', // Is handled by simple-import-sort
46
- 'import/prefer-default-export': 'off', // This is not really useful, because named exports are easier to import (IDE)
47
- 'import/no-default-export': 'error', // Prefer named exports over default exports since they are easier to find and refactor
48
- 'import/extensions': [
49
- 'error',
50
- 'always',
51
- {
52
- ignorePackages: true,
53
- js: 'always',
54
- },
55
- ],
56
- 'simple-import-sort/exports': 'error',
57
- 'simple-import-sort/imports': [
58
- 'error',
59
- {
60
- /**
61
- * The default grouping, but with type imports last as a separate group.
62
- * From https://github.com/lydell/eslint-plugin-simple-import-sort/blob/37f9448cdfed85dacf27e34c515653ff96f0377a/examples/.eslintrc.js.
63
- */
64
- groups: [['^\\u0000'], ['^@?\\w'], ['^'], ['^\\.'], ['^.+\\u0000$']],
65
- },
66
- ],
67
- '@typescript-eslint/no-use-before-define': ['error', {functions: false}], // function declarations are always
68
- // hoisted so it's safe
69
- '@typescript-eslint/lines-between-class-members': [
70
- 'error',
71
- 'always',
72
- {exceptAfterSingleLine: true},
73
- ], // Avoid blowing up classes
74
-
75
- // Forbid the use of extraneous packages
76
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
77
- // paths are treated both as absolute paths, and relative to process.cwd()
78
- 'import/no-extraneous-dependencies': [
79
- 'error',
80
- {
81
- devDependencies: [
82
- '**/setupTests.{js,ts}', // test setup files
83
- 'test/**', // tape, common npm pattern
84
- 'tests/**', // also common npm pattern
85
- 'spec/**', // mocha, rspec-like pattern
86
- '**/__tests__/**', // jest pattern
87
- '**/__mocks__/**', // jest pattern
88
- 'test.{js,jsx}', // repos with a single test file
89
- 'test-*.{js,jsx}', // repos with multiple top-level test files
90
- '**/*{.,_}{test,spec}.{js,jsx}', // tests where the extension or filename suffix denotes that it is a test
91
- '**/jest.config.js', // jest config
92
- '**/jest.setup.js', // jest setup
93
- '**/vue.config.js', // vue-cli config
94
- '**/webpack.config.js', // webpack config
95
- '**/webpack.config.*.js', // webpack config
96
- '**/rollup.config.js', // rollup config
97
- '**/rollup.config.*.js', // rollup config
98
- '**/gulpfile.js', // gulp config
99
- '**/gulpfile.*.js', // gulp config
100
- '**/Gruntfile{,.js}', // grunt config
101
- '**/protractor.conf.js', // protractor config
102
- '**/protractor.conf.*.js', // protractor config
103
- '**/karma.conf.js', // karma config
104
- '**/.eslintrc.js', // eslint config
105
- ],
106
- optionalDependencies: false,
107
- },
108
- ],
109
- 'react/prop-types': 'off', // Since we do not use prop-types
110
- 'react/require-default-props': 'off', // Since we do not use prop-types
111
- // Many of our loops are server side rendered, so we can rely on the index in general
112
- 'react/no-array-index-key': 0,
113
- // To support hydration of components, a string is necessary so that the minification of bundles
114
- // do not affect our markup generation on the server.
115
- 'react/display-name': [2, {ignoreTranspilerName: true}],
116
- // aria roles ignored (0) instead of warning (1) / errors (2).
117
- 'jsx-a11y/role-supports-aria-props': 0,
118
- 'react/function-component-definition': [2, {namedComponents: 'arrow-function'}],
119
- // Conditional spreads are easier to do so we can deactivate this rule
120
- 'react/jsx-props-no-spreading': 0,
121
- // Enforce the definition of Fragment instead of shorthand syntax.
122
- // The thing is, that keys can only be applied to the long version. So we should stick to one version.
123
- 'react/jsx-fragments': [2, 'element'],
124
- // We need to use setDangerouslyInnerHtml for article and server side rendered markup prepared by external helpers.
125
- // So it makes no sense to have this rule in place.
126
- 'react/no-danger': 0,
127
- // strict null-checking is not necessary.
128
- // The syntax itself should be avoided for sure but in some cases where we know we get the data,
129
- // we can use this functionality
130
- '@typescript-eslint/no-non-null-assertion': 0,
131
- },
132
- };
@@ -1,46 +0,0 @@
1
- name: Deploy Docs
2
-
3
- on:
4
- push:
5
- branches: [master]
6
- workflow_dispatch:
7
-
8
- permissions:
9
- contents: read
10
- pages: write
11
- id-token: write
12
-
13
- concurrency:
14
- group: pages
15
- cancel-in-progress: true
16
-
17
- jobs:
18
- build:
19
- runs-on: ubuntu-latest
20
- steps:
21
- - name: Checkout
22
- uses: actions/checkout@v4
23
- - name: Setup Node
24
- uses: actions/setup-node@v4
25
- with:
26
- node-version: 20
27
- cache: npm
28
- - name: Install dependencies
29
- run: npm ci
30
- - name: Build docs
31
- run: npm run docs:build
32
- - name: Upload artifact
33
- uses: actions/upload-pages-artifact@v3
34
- with:
35
- path: ./docs
36
-
37
- deploy:
38
- runs-on: ubuntu-latest
39
- needs: build
40
- environment:
41
- name: github-pages
42
- url: ${{ steps.deployment.outputs.page_url }}
43
- steps:
44
- - name: Deploy
45
- id: deployment
46
- uses: actions/deploy-pages@v4
@@ -1,33 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- permissions:
9
- contents: write
10
-
11
- jobs:
12
- release:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - name: Checkout
16
- uses: actions/checkout@v4
17
- - name: Setup Node
18
- uses: actions/setup-node@v4
19
- with:
20
- node-version: 20
21
- cache: npm
22
- - name: Install dependencies
23
- run: npm ci
24
- - name: Build dist
25
- run: npm run build
26
- - name: Package dist
27
- run: |
28
- zip -r "dist-${{ github.ref_name }}.zip" dist
29
- - name: Create GitHub release
30
- uses: softprops/action-gh-release@v2
31
- with:
32
- files: dist-${{ github.ref_name }}.zip
33
- generate_release_notes: true
package/.nvmrc DELETED
@@ -1 +0,0 @@
1
- v22
package/.prettierrc DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "useTabs": false,
3
- "printWidth": 100,
4
- "singleQuote": true,
5
- "trailingComma": "es5",
6
- "semi": true
7
- }
@@ -1 +0,0 @@
1
- @import"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap";code[class*=language-],pre[class*=language-]{color:#ccc;background:none;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999}.token.punctuation{color:#ccc}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.number,.token.function{color:#f08d49}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699}.token.operator,.token.entity,.token.url{color:#67cdcc}.token.important,.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}:root{color-scheme:light;--bg: #f3f2ee;--bg-strong: #e6e1d8;--card: #ffffff;--ink: #1b1b1f;--muted: #5c5c66;--accent: #2f6bff;--accent-soft: #c9d8ff;--accent-2: #ff9f1c;--shadow: 0 18px 45px -30px rgba(0, 0, 0, .45);--radius-lg: 28px;--radius-md: 18px;--radius-sm: 12px;--panel-dark: #0e1116;font-family:Space Grotesk,system-ui,-apple-system,sans-serif}*{box-sizing:border-box}body{margin:0;min-height:100vh;color:var(--ink);background:radial-gradient(circle at 20% 20%,rgba(47,107,255,.18),transparent 55%),radial-gradient(circle at 80% 0%,rgba(255,159,28,.2),transparent 50%),linear-gradient(160deg,var(--bg),var(--bg-strong))}#root{min-height:100vh}.app{max-width:1100px;margin:0 auto;padding:56px 28px 72px;display:flex;flex-direction:column;gap:40px}.brand-bar{display:inline-flex;align-items:center;gap:10px;font-weight:600;justify-content:center;width:100%}.brand-logo{width:260px;height:auto;display:block}.nav{display:flex;align-items:center;justify-content:center;flex-direction:column;padding:10px 6px;width:100%}.nav-toggle{display:none;border:1px solid rgba(27,27,31,.18);background:#ffffffd9;color:var(--ink);border-radius:999px;padding:8px 14px;font:inherit;font-weight:600;cursor:pointer;box-shadow:var(--shadow)}.nav-links{display:inline-flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;padding:6px 12px;width:min(100%,980px);background:#ffffffb3;border-radius:999px;border:1px solid rgba(27,27,31,.1);box-shadow:var(--shadow)}.nav-links a{text-decoration:none;color:var(--ink);font-weight:500;padding:6px 12px;border-radius:999px;transition:background .2s ease,color .2s ease}.nav-links a:hover{background:#2f6bff1f;color:var(--accent)}.hero{display:grid;gap:16px;padding:32px 34px;background:#ffffffbf;border-radius:var(--radius-lg);box-shadow:var(--shadow);border:1px solid rgba(27,27,31,.08);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);animation:fade-up .6s ease both}.hero.intro{gap:18px}h1{font-size:clamp(2rem,1.6vw + 1.4rem,2.8rem);line-height:1.15;margin:0}h2{margin:0;font-size:1.4rem}h3{margin:0 0 8px}p{margin:0;color:var(--muted);line-height:1.6}p span{font-family:monospace;font-weight:700;font-size:.9rem}.muted{color:var(--muted)}.eyebrow{font-family:IBM Plex Mono,ui-monospace,SFMono-Regular,monospace;text-transform:uppercase;letter-spacing:.18em;font-size:.7rem;color:var(--muted);margin-bottom:10px}.subtext{max-width:600px}.hero .subtext{margin-top:12px}.hero .subtext+.subtext{margin-top:10px}.grid{display:grid;gap:24px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));align-items:stretch}.doc-section{display:grid;gap:18px;padding:28px;border-radius:var(--radius-md);background:#ffffffd9;border:1px solid rgba(27,27,31,.08);box-shadow:var(--shadow)}.doc-copy{display:grid;gap:10px}.doc-snippets{display:grid;gap:12px}.singleton-grid{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));align-items:stretch}.singleton-card{background:#fff;border-radius:var(--radius-md);padding:22px;border:1px solid rgba(27,27,31,.08);box-shadow:var(--shadow);display:grid;gap:14px;align-content:start;height:100%}.singleton-count{font-size:2.4rem;font-weight:700;color:var(--ink);background:var(--bg-strong);border-radius:var(--radius-sm);padding:10px 16px;width:fit-content}.singleton-count.highlight{background:#2f6bff29;color:var(--accent)}.singleton-hint{font-size:.85rem;color:var(--muted)}.guide{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));align-items:stretch}.api-flow{display:grid;gap:30px}.api-group{display:grid;gap:18px}.api-grid{display:grid;gap:18px;grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch}.api-composition-card{padding:2px 0 18px;border-bottom:1px solid rgba(27,27,31,.16);display:grid;gap:10px;align-content:start}.api-composition-card h3{margin:0;font-size:1rem}.api-composition-punch{margin-top:8px;font-weight:600;color:var(--ink);background:linear-gradient(120deg,#2f6bff24,#ff9f1c24);border:1px solid rgba(47,107,255,.2);border-radius:var(--radius-sm);padding:10px 12px}.api-card{background:#fff;border-radius:var(--radius-sm);padding:18px;border:1px solid rgba(27,27,31,.08);box-shadow:var(--shadow);display:grid;gap:10px;align-content:start;height:100%}.api-card h3{margin:0;font-size:1rem}.api-card-wide{grid-column:1 / -1}.philosophy-grid{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));align-items:stretch}.philosophy-card{background:#fff;border-radius:var(--radius-md);border:1px solid rgba(27,27,31,.08);box-shadow:var(--shadow);overflow:hidden;display:grid;gap:16px;align-content:start;height:100%}.philosophy-card img{width:100%;height:190px;object-fit:cover;background:var(--panel-dark)}.philosophy-card div{padding:0 20px 22px;display:grid;gap:8px}.guide-card{background:#ffffffd9;border-radius:var(--radius-md);padding:22px;border:1px solid rgba(27,27,31,.08);box-shadow:var(--shadow);display:grid;gap:16px;align-content:start;height:100%}.guide-highlight{margin-top:4px;font-weight:600;color:var(--ink);background:linear-gradient(120deg,#2f6bff29,#ff9f1c29);border:1px solid rgba(47,107,255,.2);border-radius:var(--radius-sm);padding:10px 12px}.code-block.compact{font-size:.75rem;padding:12px 14px}.card{background:var(--card);border-radius:var(--radius-md);padding:24px;box-shadow:var(--shadow);border:1px solid rgba(27,27,31,.08);display:flex;flex-direction:column;gap:20px;animation:fade-up .6s ease both;height:100%}.card:nth-child(2){animation-delay:.1s}.card-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.count-chip{background:var(--accent-soft);color:var(--accent);border-radius:999px;padding:6px 14px;font-weight:600;font-size:1rem}.count-display{display:grid;gap:8px;padding:16px;border-radius:var(--radius-sm);background:linear-gradient(120deg,#2f6bff1a,#ff9f1c14)}.code-block{margin:0;padding:16px 18px;border-radius:var(--radius-sm);background:#12131a;color:#f0f2ff;font-family:IBM Plex Mono,ui-monospace,SFMono-Regular,monospace;font-size:.8rem;line-height:1.5;overflow-x:auto;box-shadow:inset 0 0 0 1px #ffffff14}.code-block code{font-family:inherit}.count-label{font-size:.85rem;color:var(--muted)}.count-value{font-size:2.6rem;font-weight:700}.actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px}.btn{border:1px solid rgba(27,27,31,.18);border-radius:999px;padding:10px 14px;font:inherit;background:#fff;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease,border .2s ease}.btn:hover{transform:translateY(-1px);box-shadow:0 10px 20px -14px #1b1b1f66}.btn.primary{background:var(--accent);color:#fff;border-color:transparent}.btn.ghost{background:transparent;color:var(--ink)}@keyframes fade-up{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@media (max-width: 720px){.app{padding:40px 20px 60px}.nav{padding:0}.nav-toggle{display:inline-flex;align-items:center;justify-content:center;margin-bottom:10px}.nav-links{display:none;width:100%;border-radius:var(--radius-md);padding:10px;gap:8px}.nav-links.is-open{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.nav-links a{text-align:center}.doc-section{padding:22px}.api-grid{grid-template-columns:1fr}.hero{padding:26px}.footer-card{flex-direction:column;align-items:flex-start}}