fractostate 1.0.0 → 1.0.2

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 (52) hide show
  1. package/dist/cjs/index.js +2 -0
  2. package/dist/cjs/package.json +3 -0
  3. package/dist/cjs/src/index.js +66 -0
  4. package/dist/cjs/src/index.js.map +1 -0
  5. package/dist/cjs/src/proxy.js +289 -0
  6. package/dist/cjs/src/proxy.js.map +1 -0
  7. package/dist/cjs/src/store.js +373 -0
  8. package/dist/cjs/src/store.js.map +1 -0
  9. package/dist/esm/index.js +2 -0
  10. package/dist/esm/package.json +3 -0
  11. package/dist/esm/src/index.js +63 -0
  12. package/dist/esm/src/index.js.map +1 -0
  13. package/dist/esm/src/proxy.js +286 -0
  14. package/dist/esm/src/proxy.js.map +1 -0
  15. package/dist/esm/src/store.js +371 -0
  16. package/dist/esm/src/store.js.map +1 -0
  17. package/dist/index.d.ts +124 -0
  18. package/package.json +49 -9
  19. package/docs/api-reference.md +0 -46
  20. package/docs/architecture.md +0 -27
  21. package/docs/getting-started.md +0 -94
  22. package/src/index.ts +0 -82
  23. package/src/proxy.ts +0 -313
  24. package/src/store.ts +0 -324
  25. package/src/types.ts +0 -126
  26. package/test/README.md +0 -73
  27. package/test/eslint.config.js +0 -23
  28. package/test/index.html +0 -13
  29. package/test/package.json +0 -47
  30. package/test/postcss.config.mjs +0 -7
  31. package/test/public/vite.svg +0 -1
  32. package/test/src/App.css +0 -42
  33. package/test/src/App.tsx +0 -44
  34. package/test/src/assets/react.svg +0 -1
  35. package/test/src/components/CartDrawer.tsx +0 -79
  36. package/test/src/components/Navbar.tsx +0 -48
  37. package/test/src/components/Notifications.tsx +0 -27
  38. package/test/src/components/ProductList.tsx +0 -56
  39. package/test/src/flows.ts +0 -7
  40. package/test/src/index.css +0 -33
  41. package/test/src/layout/Layout.tsx +0 -68
  42. package/test/src/layout/ProtectedRoute.tsx +0 -19
  43. package/test/src/main.tsx +0 -10
  44. package/test/src/pages/LoginPage.tsx +0 -86
  45. package/test/src/pages/ProfilePage.tsx +0 -48
  46. package/test/src/pages/ShopPage.tsx +0 -54
  47. package/test/src/store/auth.ts +0 -39
  48. package/test/src/store/flows.ts +0 -74
  49. package/test/tsconfig.app.json +0 -31
  50. package/test/tsconfig.json +0 -7
  51. package/test/tsconfig.node.json +0 -29
  52. package/test/vite.config.ts +0 -16
package/src/store.ts DELETED
@@ -1,324 +0,0 @@
1
- import type { FlowOptions } from "./types";
2
-
3
- /**
4
- * Fast & Secure Memory Vault
5
- * Ultra-performant in-memory store with deep cloning and batching
6
- * NO PERSISTENCE - Pure memory for maximum safety and speed
7
- */
8
- class SecureVault {
9
- private vault = new Map<string, any>();
10
- private initialValues = new Map<string, any>();
11
- private listeners = new Map<string, Set<() => void>>();
12
- private histories = new Map<string, CircularBuffer<any>>();
13
- private redoStacks = new Map<string, any[]>();
14
- private debounceTimers = new Map<string, number>();
15
- private batchQueue = new Set<string>();
16
- private batchScheduled = false;
17
-
18
- constructor() {
19
- this.setupSecureAccess();
20
- this.setupAutoCleanup();
21
- }
22
-
23
- /**
24
- * Protects the vault instance from global window inspection.
25
- */
26
- private setupSecureAccess() {
27
- if (typeof window !== "undefined") {
28
- Object.defineProperty(window, "__FRACTO_VAULT__", {
29
- get: () => "🔒 Access Denied: Secure Memory Instance",
30
- configurable: false,
31
- });
32
- }
33
- }
34
-
35
- /**
36
- * Periodically cleans up orphaned listeners.
37
- */
38
- private setupAutoCleanup() {
39
- if (typeof setInterval !== "undefined") {
40
- setInterval(() => {
41
- this.listeners.forEach((set, key) => {
42
- if (set.size === 0 && !this.vault.has(key)) {
43
- this.listeners.delete(key);
44
- }
45
- });
46
- }, 300000); // 5 min
47
- }
48
- }
49
-
50
- /**
51
- * Lightweight but ultra-fast obfuscation for memory protection.
52
- */
53
- private obfuscate(data: any): any {
54
- if (data === undefined) return undefined;
55
- try {
56
- const str = JSON.stringify(data);
57
- // Simple scrambling to prevent plain-text memory inspection
58
- return { _: btoa(encodeURIComponent(str)), t: Date.now() };
59
- } catch {
60
- return data;
61
- }
62
- }
63
-
64
- /**
65
- * Reverts obfuscation to retrieve original data structure.
66
- */
67
- private deobfuscate(vaultItem: any): any {
68
- if (!vaultItem || typeof vaultItem !== "object" || !vaultItem._)
69
- return vaultItem;
70
- try {
71
- const decoded = decodeURIComponent(atob(vaultItem._));
72
- return JSON.parse(decoded);
73
- } catch {
74
- return undefined;
75
- }
76
- }
77
-
78
- /**
79
- * Retrieves state from the vault. Initializes if a value is provided and the key is missing.
80
- */
81
- get(key: string, initialValue?: any) {
82
- if (!this.vault.has(key)) {
83
- if (initialValue === undefined) return undefined;
84
-
85
- const cloned = deepClone(initialValue);
86
- this.vault.set(key, this.obfuscate(cloned));
87
- this.initialValues.set(key, deepClone(cloned));
88
- this.histories.set(key, new CircularBuffer(100, [cloned]));
89
- this.redoStacks.set(key, []);
90
- }
91
-
92
- const val = this.deobfuscate(this.vault.get(key));
93
- return val === undefined ? initialValue : val;
94
- }
95
-
96
- /**
97
- * Updates state in the vault with optional debouncing and middleware support.
98
- */
99
- set(key: string, newValue: any, options: FlowOptions = {}) {
100
- const prevState = this.deobfuscate(this.vault.get(key));
101
- let stateToSet = deepClone(newValue);
102
-
103
- // Apply synchronous middleware
104
- if (options.middleware) {
105
- for (const fn of options.middleware) {
106
- stateToSet = fn(stateToSet);
107
- }
108
- }
109
-
110
- // Skip update if state has not changed (Deep equality check)
111
- if (deepEqual(prevState, stateToSet)) return;
112
-
113
- if (options.debounce) {
114
- this.debouncedSet(key, stateToSet, options);
115
- return;
116
- }
117
-
118
- this.applySet(key, stateToSet, options);
119
- }
120
-
121
- /**
122
- * Executes a debounced state update.
123
- */
124
- private debouncedSet(key: string, value: any, options: FlowOptions) {
125
- const existing = this.debounceTimers.get(key);
126
- if (existing) clearTimeout(existing);
127
-
128
- const timer = setTimeout(() => {
129
- this.applySet(key, value, options);
130
- this.debounceTimers.delete(key);
131
- }, options.debounce);
132
-
133
- this.debounceTimers.set(key, timer as any);
134
- }
135
-
136
- /**
137
- * Core logic for applying a state update and managing history.
138
- */
139
- private applySet(key: string, stateToSet: any, options: FlowOptions) {
140
- this.vault.set(key, this.obfuscate(stateToSet));
141
-
142
- if (options.timeTravel) {
143
- const history = this.histories.get(key);
144
- if (history) history.push(deepClone(stateToSet));
145
- const redo = this.redoStacks.get(key);
146
- if (redo) redo.length = 0;
147
- }
148
-
149
- this.scheduleBatchNotify(key);
150
- }
151
-
152
- /**
153
- * Schedules a microtask to batch notifications and optimize React renders.
154
- */
155
- private scheduleBatchNotify(key: string) {
156
- this.batchQueue.add(key);
157
- if (this.batchScheduled) return;
158
- this.batchScheduled = true;
159
- queueMicrotask(() => this.flushBatchNotify());
160
- }
161
-
162
- /**
163
- * Flushes and notifies all queued listeners.
164
- */
165
- private flushBatchNotify() {
166
- const keys = Array.from(this.batchQueue);
167
- this.batchQueue.clear();
168
- this.batchScheduled = false;
169
- keys.forEach((key) => this.notify(key));
170
- }
171
-
172
- /**
173
- * Connects a listener to a specific flow key.
174
- */
175
- subscribe(key: string, listener: () => void) {
176
- if (!this.listeners.has(key)) this.listeners.set(key, new Set());
177
- this.listeners.get(key)!.add(listener);
178
- return () => {
179
- this.listeners.get(key)?.delete(listener);
180
- };
181
- }
182
-
183
- /**
184
- * Directly notifies all listeners of a specific key.
185
- */
186
- private notify(key: string) {
187
- this.listeners.get(key)?.forEach((l) => l());
188
- }
189
-
190
- /**
191
- * Reverts the state to the previous version in history.
192
- */
193
- undo(key: string) {
194
- const history = this.histories.get(key);
195
- const redo = this.redoStacks.get(key);
196
- if (history && history.length() > 1) {
197
- const current = history.pop();
198
- if (current) redo?.push(current);
199
- const prev = history.peek();
200
- this.vault.set(key, this.obfuscate(prev));
201
- this.notify(key);
202
- }
203
- }
204
-
205
- /**
206
- * Restores the state to the next version in the redo stack.
207
- */
208
- redo(key: string) {
209
- const history = this.histories.get(key);
210
- const redo = this.redoStacks.get(key);
211
- if (redo && redo.length > 0) {
212
- const next = redo.pop();
213
- history?.push(next);
214
- this.vault.set(key, this.obfuscate(next));
215
- this.notify(key);
216
- }
217
- }
218
-
219
- /**
220
- * Resets a flow to its initial value.
221
- */
222
- reset(key: string) {
223
- const initial = this.initialValues.get(key);
224
- if (initial !== undefined) this.set(key, initial);
225
- }
226
-
227
- getHistory(key: string) {
228
- return this.histories.get(key)?.toArray() || [];
229
- }
230
- getRedoStack(key: string) {
231
- return this.redoStacks.get(key) || [];
232
- }
233
-
234
- /**
235
- * Clears the entire store and all timers.
236
- */
237
- clearAll() {
238
- this.debounceTimers.forEach((t) => clearTimeout(t));
239
- this.vault.clear();
240
- this.initialValues.clear();
241
- this.listeners.clear();
242
- this.histories.clear();
243
- this.redoStacks.clear();
244
- }
245
- }
246
-
247
- /**
248
- * Circular Buffer implementation for high-performance memory-efficient history.
249
- */
250
- class CircularBuffer<T> {
251
- private buffer: T[];
252
- private head = 0;
253
- private size = 0;
254
- private maxSize: number;
255
-
256
- constructor(maxSize: number, initial: T[] = []) {
257
- this.maxSize = maxSize;
258
- this.buffer = new Array(maxSize);
259
- initial.forEach((i) => this.push(i));
260
- }
261
- push(item: T) {
262
- this.buffer[this.head] = item;
263
- this.head = (this.head + 1) % this.maxSize;
264
- if (this.size < this.maxSize) this.size++;
265
- }
266
- pop(): T | undefined {
267
- if (this.size <= 0) return undefined;
268
- this.head = (this.head - 1 + this.maxSize) % this.maxSize;
269
- this.size--;
270
- return this.buffer[this.head];
271
- }
272
- peek(): T | undefined {
273
- return this.size > 0
274
- ? this.buffer[(this.head - 1 + this.maxSize) % this.maxSize]
275
- : undefined;
276
- }
277
- length() {
278
- return this.size;
279
- }
280
- toArray(): T[] {
281
- const res = [];
282
- for (let i = 0; i < this.size; i++) {
283
- res.push(
284
- this.buffer[(this.head - this.size + i + this.maxSize) % this.maxSize],
285
- );
286
- }
287
- return res;
288
- }
289
- }
290
-
291
- /**
292
- * High-performance deep cloning utility.
293
- */
294
- function deepClone<T>(obj: T): T {
295
- if (obj === null || typeof obj !== "object") return obj;
296
- if (Array.isArray(obj)) return obj.map(deepClone) as any;
297
- const cloned: any = {};
298
- for (const key in obj) {
299
- if (Object.prototype.hasOwnProperty.call(obj, key))
300
- cloned[key] = deepClone(obj[key]);
301
- }
302
- return cloned;
303
- }
304
-
305
- /**
306
- * High-performance deep equality utility.
307
- */
308
- function deepEqual(a: any, b: any): boolean {
309
- if (a === b) return true;
310
- if (typeof a !== typeof b || a === null || b === null) return false;
311
- if (typeof a === "object") {
312
- const keysA = Object.keys(a);
313
- const keysB = Object.keys(b);
314
- if (keysA.length !== keysB.length) return false;
315
- for (const key of keysA) {
316
- if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
317
- if (!deepEqual(a[key], b[key])) return false;
318
- }
319
- return true;
320
- }
321
- return false;
322
- }
323
-
324
- export const store = new SecureVault();
package/src/types.ts DELETED
@@ -1,126 +0,0 @@
1
- export interface FlowOptions<T = any> {
2
- /** Enable history tracking for undo/redo functionality */
3
- timeTravel?: boolean;
4
- /** Maximum number of states to keep in history (default: 100) */
5
- maxHistory?: number;
6
- /** Debounce state updates in milliseconds */
7
- debounce?: number;
8
- /** Array of functions to transform state before it is saved */
9
- middleware?: Array<(state: T) => T>;
10
- }
11
-
12
- export type BaseOps<T> = {
13
- /** Replaces the entire value at this path */
14
- set: (value: T) => void;
15
- };
16
-
17
- export type NumberOps = BaseOps<number> & {
18
- /** Adds 1 (or amount) to the number */
19
- increment: (amount?: number) => void;
20
- /** Subtracts 1 (or amount) from the number */
21
- decrement: (amount?: number) => void;
22
- /** Adds the given amount */
23
- add: (amount: number) => void;
24
- /** Subtracts the given amount */
25
- subtract: (amount: number) => void;
26
- /** Multiplies by the given amount */
27
- multiply: (amount: number) => void;
28
- /** Divides by the given amount */
29
- divide: (amount: number) => void;
30
- };
31
-
32
- export type StringOps = BaseOps<string> & {
33
- /** Appends a string to the end */
34
- append: (str: string) => void;
35
- /** Prepends a string to the beginning */
36
- prepend: (str: string) => void;
37
- /** Converts to uppercase */
38
- uppercase: () => void;
39
- /** Converts to lowercase */
40
- lowercase: () => void;
41
- /** Removes whitespace from both ends */
42
- trim: () => void;
43
- /** Replaces a substring or regex match */
44
- replace: (search: string | RegExp, replace: string) => void;
45
- };
46
-
47
- export type ArrayOps<T> = BaseOps<T[]> & {
48
- /** Appends an item to the end */
49
- push: (item: T) => void;
50
- /** Removes the last item */
51
- pop: () => void;
52
- /** Removes the first item */
53
- shift: () => void;
54
- /** Adds an item to the beginning */
55
- unshift: (item: T) => void;
56
- /** Filters the array based on a predicate */
57
- filter: (predicate: (item: T, index: number) => boolean) => void;
58
- /** Transforms each item in the array */
59
- map: (fn: (item: T, index: number) => T) => void;
60
- /** Adds/removes items at a specific index */
61
- splice: (start: number, deleteCount?: number, ...items: T[]) => void;
62
- /** Removes the item at the specified index */
63
- removeAt: (index: number) => void;
64
- /** Inserts an item at the specified index */
65
- insertAt: (index: number, item: T) => void;
66
- };
67
-
68
- export type ObjectOps<T> = BaseOps<T> & {
69
- /** Merges the given object into the current one */
70
- merge: (partial: Partial<T>) => void;
71
- /** Deletes a property from the object */
72
- delete: (key: keyof T) => void;
73
- } & {
74
- /** Recursive access to nested properties */
75
- [K in keyof T]-?: TypeAwareOps<T[K]>;
76
- };
77
-
78
- export type BooleanOps = BaseOps<boolean> & {
79
- /** Inverts the current boolean value */
80
- toggle: () => void;
81
- };
82
-
83
- export type TypeAwareOps<T> = T extends number
84
- ? NumberOps
85
- : T extends string
86
- ? StringOps
87
- : T extends boolean
88
- ? BooleanOps
89
- : T extends Array<infer U>
90
- ? ArrayOps<U>
91
- : T extends object
92
- ? ObjectOps<T>
93
- : BaseOps<T>;
94
-
95
- export interface FlowDefinition<T> {
96
- key: string;
97
- initial: T;
98
- options?: FlowOptions<T>;
99
- }
100
-
101
- export interface FlowOperations<T> {
102
- ops: {
103
- /**
104
- * Recursive, type-aware proxy that provides surgical atomic operations
105
- * tailored to the shape of your state. It allows direct-like manipulation
106
- * that is internally processed as immutable updates.
107
- */
108
- self: TypeAwareOps<T>;
109
- };
110
- /** Reverts to the previous state in history */
111
- undo: () => void;
112
- /** Restores the previously undone state */
113
- redo: () => void;
114
- /** Array of past states (requires timeTravel: true) */
115
- history: T[];
116
- /** Whether there is a previous state to undo */
117
- canUndo: boolean;
118
- /** Whether there is a next state to redo */
119
- canRedo: boolean;
120
- /** Manually sets the entire state or applies a transformation function */
121
- set: (val: T | ((prev: T) => T)) => void;
122
- /** Restores the state to its initial value */
123
- reset: () => void;
124
- /** Current flow configuration options */
125
- cf: FlowOptions<T>;
126
- }
package/test/README.md DELETED
@@ -1,73 +0,0 @@
1
- # React + TypeScript + Vite
2
-
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
-
5
- Currently, two official plugins are available:
6
-
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
-
10
- ## React Compiler
11
-
12
- The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
13
-
14
- ## Expanding the ESLint configuration
15
-
16
- If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
17
-
18
- ```js
19
- export default defineConfig([
20
- globalIgnores(['dist']),
21
- {
22
- files: ['**/*.{ts,tsx}'],
23
- extends: [
24
- // Other configs...
25
-
26
- // Remove tseslint.configs.recommended and replace with this
27
- tseslint.configs.recommendedTypeChecked,
28
- // Alternatively, use this for stricter rules
29
- tseslint.configs.strictTypeChecked,
30
- // Optionally, add this for stylistic rules
31
- tseslint.configs.stylisticTypeChecked,
32
-
33
- // Other configs...
34
- ],
35
- languageOptions: {
36
- parserOptions: {
37
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
- tsconfigRootDir: import.meta.dirname,
39
- },
40
- // other options...
41
- },
42
- },
43
- ])
44
- ```
45
-
46
- You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
47
-
48
- ```js
49
- // eslint.config.js
50
- import reactX from 'eslint-plugin-react-x'
51
- import reactDom from 'eslint-plugin-react-dom'
52
-
53
- export default defineConfig([
54
- globalIgnores(['dist']),
55
- {
56
- files: ['**/*.{ts,tsx}'],
57
- extends: [
58
- // Other configs...
59
- // Enable lint rules for React
60
- reactX.configs['recommended-typescript'],
61
- // Enable lint rules for React DOM
62
- reactDom.configs.recommended,
63
- ],
64
- languageOptions: {
65
- parserOptions: {
66
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
- tsconfigRootDir: import.meta.dirname,
68
- },
69
- // other options...
70
- },
71
- },
72
- ])
73
- ```
@@ -1,23 +0,0 @@
1
- import js from '@eslint/js'
2
- import globals from 'globals'
3
- import reactHooks from 'eslint-plugin-react-hooks'
4
- import reactRefresh from 'eslint-plugin-react-refresh'
5
- import tseslint from 'typescript-eslint'
6
- import { defineConfig, globalIgnores } from 'eslint/config'
7
-
8
- export default defineConfig([
9
- globalIgnores(['dist']),
10
- {
11
- files: ['**/*.{ts,tsx}'],
12
- extends: [
13
- js.configs.recommended,
14
- tseslint.configs.recommended,
15
- reactHooks.configs.flat.recommended,
16
- reactRefresh.configs.vite,
17
- ],
18
- languageOptions: {
19
- ecmaVersion: 2020,
20
- globals: globals.browser,
21
- },
22
- },
23
- ])
package/test/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>test</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.tsx"></script>
12
- </body>
13
- </html>
package/test/package.json DELETED
@@ -1,47 +0,0 @@
1
- {
2
- "dependencies": {
3
- "@eslint/js": "9.39.2",
4
- "@tailwindcss/postcss": "^4.1.18",
5
- "@types/node": "24.10.9",
6
- "@types/react": "19.2.9",
7
- "@types/react-dom": "19.2.3",
8
- "@vitejs/plugin-react": "5.1.2",
9
- "autoprefixer": "^10.4.23",
10
- "eslint": "9.39.2",
11
- "eslint-plugin-react-hooks": "7.0.1",
12
- "eslint-plugin-react-refresh": "0.4.26",
13
- "globals": "16.5.0",
14
- "postcss": "^8.5.6",
15
- "react": "19.2.3",
16
- "react-dom": "19.2.3",
17
- "sql.js": "^1.13.0",
18
- "tailwindcss": "^4.1.18",
19
- "typescript": "5.9.3",
20
- "typescript-eslint": "8.53.1",
21
- "vite": "7.3.1"
22
- },
23
- "devDependencies": {
24
- "@eslint/js": "^9.39.1",
25
- "@types/node": "^24.10.1",
26
- "@types/react": "^19.2.5",
27
- "@types/react-dom": "^19.2.3",
28
- "@vitejs/plugin-react": "^5.1.1",
29
- "eslint": "^9.39.1",
30
- "eslint-plugin-react-hooks": "^7.0.1",
31
- "eslint-plugin-react-refresh": "^0.4.24",
32
- "globals": "^16.5.0",
33
- "typescript": "~5.9.3",
34
- "typescript-eslint": "^8.46.4",
35
- "vite": "^7.2.4"
36
- },
37
- "name": "test",
38
- "private": true,
39
- "scripts": {
40
- "build": "tsc -b && vite build",
41
- "dev": "vite",
42
- "lint": "eslint .",
43
- "preview": "vite preview"
44
- },
45
- "type": "module",
46
- "version": "0.0.0"
47
- }
@@ -1,7 +0,0 @@
1
- const config = {
2
- plugins: {
3
- "@tailwindcss/postcss": {},
4
- },
5
- };
6
-
7
- export default config;
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
package/test/src/App.css DELETED
@@ -1,42 +0,0 @@
1
- #root {
2
- max-width: 1280px;
3
- margin: 0 auto;
4
- padding: 2rem;
5
- text-align: center;
6
- }
7
-
8
- .logo {
9
- height: 6em;
10
- padding: 1.5em;
11
- will-change: filter;
12
- transition: filter 300ms;
13
- }
14
- .logo:hover {
15
- filter: drop-shadow(0 0 2em #646cffaa);
16
- }
17
- .logo.react:hover {
18
- filter: drop-shadow(0 0 2em #61dafbaa);
19
- }
20
-
21
- @keyframes logo-spin {
22
- from {
23
- transform: rotate(0deg);
24
- }
25
- to {
26
- transform: rotate(360deg);
27
- }
28
- }
29
-
30
- @media (prefers-reduced-motion: no-preference) {
31
- a:nth-of-type(2) .logo {
32
- animation: logo-spin infinite 20s linear;
33
- }
34
- }
35
-
36
- .card {
37
- padding: 2em;
38
- }
39
-
40
- .read-the-docs {
41
- color: #888;
42
- }