@kirill.konshin/utils 0.0.17 → 0.0.19

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 (170) hide show
  1. package/.turbo/turbo-build.log +38 -38
  2. package/.turbo/turbo-test.log +37 -37
  3. package/CHANGELOG.md +12 -0
  4. package/dist/bootstrap/adaptiveContainer.d.ts +2 -1
  5. package/dist/bootstrap/adaptiveContainer.d.ts.map +1 -1
  6. package/dist/bootstrap/adaptiveContainer.js +2 -2
  7. package/dist/bootstrap/adaptiveContainer.js.map +1 -1
  8. package/dist/bootstrap/controls.d.ts +6 -6
  9. package/dist/bootstrap/controls.d.ts.map +1 -1
  10. package/dist/bootstrap/controls.js.map +1 -1
  11. package/dist/bootstrap/error.d.ts +4 -2
  12. package/dist/bootstrap/error.d.ts.map +1 -1
  13. package/dist/bootstrap/error.js +2 -7
  14. package/dist/bootstrap/error.js.map +1 -1
  15. package/dist/bootstrap/field.d.ts +4 -2
  16. package/dist/bootstrap/field.d.ts.map +1 -1
  17. package/dist/bootstrap/field.js +2 -2
  18. package/dist/bootstrap/field.js.map +1 -1
  19. package/dist/bootstrap/footer.d.ts +5 -5
  20. package/dist/bootstrap/footer.d.ts.map +1 -1
  21. package/dist/bootstrap/footer.js +9 -4
  22. package/dist/bootstrap/footer.js.map +1 -1
  23. package/dist/bootstrap/globalLoading.d.ts +4 -2
  24. package/dist/bootstrap/globalLoading.d.ts.map +1 -1
  25. package/dist/bootstrap/globalLoading.js +2 -2
  26. package/dist/bootstrap/globalLoading.js.map +1 -1
  27. package/dist/bootstrap/loading.d.ts +4 -2
  28. package/dist/bootstrap/loading.d.ts.map +1 -1
  29. package/dist/bootstrap/loading.js +3 -2
  30. package/dist/bootstrap/loading.js.map +1 -1
  31. package/dist/bootstrap/responsiveHelper.d.ts +2 -1
  32. package/dist/bootstrap/responsiveHelper.d.ts.map +1 -1
  33. package/dist/bootstrap/responsiveHelper.js +5 -5
  34. package/dist/bootstrap/responsiveHelper.js.map +1 -1
  35. package/dist/bootstrap/screen.d.ts +4 -2
  36. package/dist/bootstrap/screen.d.ts.map +1 -1
  37. package/dist/bootstrap/screen.js +3 -2
  38. package/dist/bootstrap/screen.js.map +1 -1
  39. package/dist/bootstrap/toaster.d.ts +4 -2
  40. package/dist/bootstrap/toaster.d.ts.map +1 -1
  41. package/dist/bootstrap/toaster.js +2 -5
  42. package/dist/bootstrap/toaster.js.map +1 -1
  43. package/dist/bootstrap/useModal.d.ts +2 -1
  44. package/dist/bootstrap/useModal.d.ts.map +1 -1
  45. package/dist/bootstrap/useModal.js +3 -3
  46. package/dist/bootstrap/useModal.js.map +1 -1
  47. package/dist/bootstrap/useWrappedForm.d.ts +1 -1
  48. package/dist/bootstrap/useWrappedForm.d.ts.map +1 -1
  49. package/dist/bootstrap/useWrappedForm.js.map +1 -1
  50. package/dist/core/cache.d.ts +2 -2
  51. package/dist/core/cache.d.ts.map +1 -1
  52. package/dist/core/cache.js.map +1 -1
  53. package/dist/core/errors.d.ts.map +1 -1
  54. package/dist/core/errors.js.map +1 -1
  55. package/dist/core/files.d.ts +2 -1
  56. package/dist/core/files.d.ts.map +1 -1
  57. package/dist/core/files.js +7 -3
  58. package/dist/core/files.js.map +1 -1
  59. package/dist/core/index.js +2 -1
  60. package/dist/core/ls.d.ts +1 -1
  61. package/dist/core/ls.d.ts.map +1 -1
  62. package/dist/core/ls.js.map +1 -1
  63. package/dist/core/measure.d.ts +4 -4
  64. package/dist/core/measure.d.ts.map +1 -1
  65. package/dist/core/measure.js +5 -1
  66. package/dist/core/measure.js.map +1 -1
  67. package/dist/core/worker.d.ts +3 -3
  68. package/dist/core/worker.d.ts.map +1 -1
  69. package/dist/core/worker.js.map +1 -1
  70. package/dist/core/wrpc.d.ts +4 -4
  71. package/dist/core/wrpc.d.ts.map +1 -1
  72. package/dist/core/wrpc.fixture.d.ts +1 -4
  73. package/dist/core/wrpc.fixture.d.ts.map +1 -1
  74. package/dist/core/wrpc.js.map +1 -1
  75. package/dist/electron/createWindow.d.ts.map +1 -1
  76. package/dist/electron/createWindow.js.map +1 -1
  77. package/dist/electron/updater.d.ts +1 -1
  78. package/dist/electron/updater.d.ts.map +1 -1
  79. package/dist/electron/updater.js +1 -1
  80. package/dist/electron/updater.js.map +1 -1
  81. package/dist/electron-builder/images.d.ts.map +1 -1
  82. package/dist/electron-builder/images.js.map +1 -1
  83. package/dist/mui/formControlFieldset.d.ts +2 -2
  84. package/dist/mui/formControlFieldset.d.ts.map +1 -1
  85. package/dist/mui/formControlFieldset.js.map +1 -1
  86. package/dist/mui/formLabelLegend.d.ts +2 -2
  87. package/dist/mui/formLabelLegend.d.ts.map +1 -1
  88. package/dist/mui/formLabelLegend.js.map +1 -1
  89. package/dist/mui/genericControl.d.ts +2 -2
  90. package/dist/mui/genericControl.d.ts.map +1 -1
  91. package/dist/mui/genericControl.js.map +1 -1
  92. package/dist/mui/readOnly.d.ts +2 -2
  93. package/dist/mui/readOnly.d.ts.map +1 -1
  94. package/dist/mui/readOnly.js.map +1 -1
  95. package/dist/next/measure.d.ts.map +1 -1
  96. package/dist/next/measure.js.map +1 -1
  97. package/dist/next/noSSR.d.ts +27 -3
  98. package/dist/next/noSSR.d.ts.map +1 -1
  99. package/dist/next/noSSR.js +2 -4
  100. package/dist/next/noSSR.js.map +1 -1
  101. package/dist/react/form/client.d.ts.map +1 -1
  102. package/dist/react/form/client.js.map +1 -1
  103. package/dist/react/form/form.d.ts +22 -8
  104. package/dist/react/form/form.d.ts.map +1 -1
  105. package/dist/react/form/form.js +27 -7
  106. package/dist/react/form/form.js.map +1 -1
  107. package/dist/react/index.js +2 -1
  108. package/dist/react/keyboard.d.ts +5 -6
  109. package/dist/react/keyboard.d.ts.map +1 -1
  110. package/dist/react/keyboard.js.map +1 -1
  111. package/dist/react/useFetcher.d.ts.map +1 -1
  112. package/dist/react/useFetcher.js.map +1 -1
  113. package/dist/react-native/share.d.ts +1 -1
  114. package/dist/react-native/share.d.ts.map +1 -1
  115. package/dist/react-native/share.js.map +1 -1
  116. package/dist/react-native/update.d.ts +2 -3
  117. package/dist/react-native/update.d.ts.map +1 -1
  118. package/dist/react-native/update.js +2 -2
  119. package/dist/react-native/update.js.map +1 -1
  120. package/dist/react-native/useAppState.d.ts +1 -1
  121. package/dist/react-native/useAppState.d.ts.map +1 -1
  122. package/dist/react-native/useAppState.js.map +1 -1
  123. package/dist/tailwind/fullpage.d.ts +2 -6
  124. package/dist/tailwind/fullpage.d.ts.map +1 -1
  125. package/dist/tailwind/fullpage.js.map +1 -1
  126. package/dist/tailwind/responsiveHelper.d.ts +2 -1
  127. package/dist/tailwind/responsiveHelper.d.ts.map +1 -1
  128. package/dist/tailwind/responsiveHelper.js +2 -2
  129. package/dist/tailwind/responsiveHelper.js.map +1 -1
  130. package/package.json +1 -1
  131. package/src/bootstrap/adaptiveContainer.tsx +3 -3
  132. package/src/bootstrap/controls.stories.tsx +1 -1
  133. package/src/bootstrap/controls.tsx +12 -12
  134. package/src/bootstrap/error.tsx +7 -10
  135. package/src/bootstrap/field.tsx +11 -9
  136. package/src/bootstrap/footer.tsx +17 -5
  137. package/src/bootstrap/globalLoading.tsx +5 -3
  138. package/src/bootstrap/loading.tsx +10 -8
  139. package/src/bootstrap/responsiveHelper.tsx +11 -6
  140. package/src/bootstrap/screen.tsx +24 -22
  141. package/src/bootstrap/toaster.tsx +8 -6
  142. package/src/bootstrap/useModal.tsx +12 -7
  143. package/src/bootstrap/useWrappedForm.ts +9 -7
  144. package/src/core/cache.ts +15 -8
  145. package/src/core/errors.ts +4 -1
  146. package/src/core/files.ts +8 -4
  147. package/src/core/ls.ts +8 -4
  148. package/src/core/measure.ts +55 -7
  149. package/src/core/worker.ts +18 -11
  150. package/src/core/wrpc.fixture.ts +40 -6
  151. package/src/core/wrpc.ts +23 -5
  152. package/src/electron/createWindow.ts +3 -3
  153. package/src/electron/updater.ts +1 -1
  154. package/src/electron-builder/images.ts +1 -1
  155. package/src/mui/formControlFieldset.tsx +2 -2
  156. package/src/mui/formLabelLegend.tsx +2 -2
  157. package/src/mui/genericControl.tsx +2 -2
  158. package/src/mui/readOnly.tsx +2 -2
  159. package/src/next/measure.ts +19 -2
  160. package/src/next/noSSR.tsx +26 -7
  161. package/src/react/form/client.tsx +13 -2
  162. package/src/react/form/form.tsx +67 -18
  163. package/src/react/keyboard.tsx +9 -4
  164. package/src/react/useFetcher.ts +8 -3
  165. package/src/react-native/share.ts +1 -1
  166. package/src/react-native/update.tsx +3 -3
  167. package/src/react-native/useAppState.ts +1 -1
  168. package/src/tailwind/fullpage.tsx +2 -2
  169. package/src/tailwind/responsiveHelper.tsx +3 -3
  170. package/tsconfig.json +1 -0
@@ -44,7 +44,7 @@ function checkMessage(obj: any, message: any) {
44
44
  // Classes
45
45
 
46
46
  export class WorkerDialog<R extends RespondersBase<any>> {
47
- readonly contexts = new Set<Context<R, keyof R>>();
47
+ readonly contexts: Set<Context<R, keyof R>> = new Set();
48
48
  protected closed = false;
49
49
  protected currentId = 0; // IDs are intentionally not global
50
50
 
@@ -90,16 +90,16 @@ export class WorkerDialog<R extends RespondersBase<any>> {
90
90
  }
91
91
  }
92
92
 
93
- getID() {
93
+ getID(): string {
94
94
  return (++this.currentId).toString();
95
95
  }
96
96
 
97
- close() {
97
+ close(): void {
98
98
  for (const context of this.contexts) context.close('root');
99
99
  this.contexts.clear();
100
100
  }
101
101
 
102
- withMessage<M extends keyof R>(message: M) {
102
+ withMessage<M extends keyof R>(message: M): RequestContext<R, M> {
103
103
  return new RequestContext<R, M>(this, message, this.getID()); // always new context
104
104
  }
105
105
  }
@@ -116,7 +116,7 @@ export class RespondersBase<R> {
116
116
 
117
117
  // can only be used to create actual contexts, carries the context data
118
118
  abstract class Context<R, M extends keyof R> {
119
- protected readonly unsub = new Set<() => void>();
119
+ protected readonly unsub: Set<() => void> = new Set();
120
120
  protected closed = false;
121
121
 
122
122
  constructor(
@@ -135,7 +135,7 @@ abstract class Context<R, M extends keyof R> {
135
135
 
136
136
  abstract withMessage<M2 extends keyof R>(message: M2, id?: string): Context<R, M2>;
137
137
 
138
- close(reason: string = 'external') {
138
+ close(reason: string = 'external'): void {
139
139
  /* v8 ignore next */
140
140
  if (this.dialog.debug >= 2) console.log('Closing', this.info, reason, this);
141
141
 
@@ -157,7 +157,14 @@ abstract class Context<R, M extends keyof R> {
157
157
  return `${this.dialog.name}:${this.parent?.id ?? ALL}/${this.id}:${this.message.toString()}[${this.closed ? 'closed' : 'open'},${this.type}]`;
158
158
  }
159
159
 
160
- get debugInfo() {
160
+ get debugInfo(): {
161
+ id?: string;
162
+ parentId?: string;
163
+ message: string | number | symbol;
164
+ closed: boolean;
165
+ type: string;
166
+ listeners: number;
167
+ } {
161
168
  return {
162
169
  id: this.id,
163
170
  parentId: this.parent?.id,
@@ -170,7 +177,7 @@ abstract class Context<R, M extends keyof R> {
170
177
 
171
178
  abstract type: 'request' | 'response' | string;
172
179
 
173
- protected postMessage(data?: Data<R, M>, done = false) {
180
+ protected postMessage(data?: Data<R, M>, done = false): Data<R, M> | undefined {
174
181
  checkClosed(this, 'postMessage');
175
182
 
176
183
  const transfer = getTransferrable(data);
@@ -190,7 +197,7 @@ abstract class Context<R, M extends keyof R> {
190
197
  return data;
191
198
  }
192
199
 
193
- send(data?: Data<R, M>, done = false) {
200
+ send(data?: Data<R, M>, done = false): Data<R, M> | undefined {
194
201
  return this.postMessage(data, done);
195
202
  }
196
203
 
@@ -303,11 +310,11 @@ class RequestContext<R, M extends keyof R> extends Context<R, M> {
303
310
  return res[1];
304
311
  }
305
312
 
306
- protected async expect() {
313
+ protected async expect(): Promise<MethodReturn<R, M>> {
307
314
  checkClosed(this, 'expect');
308
315
 
309
316
  //FIXME Manual promise type
310
- return new Promise<MethodReturn<R, M>>((resolve, reject) => {
317
+ return new Promise((resolve, reject) => {
311
318
  const responseListener = this.listen(async (data) => {
312
319
  try {
313
320
  if ((data as any) instanceof Error) throw data;
@@ -1,15 +1,47 @@
1
1
  import { wrpc } from './wrpc';
2
2
 
3
- export const responder = wrpc().createResponder(self, {
3
+ export const responder: {
4
+ responders: {
5
+ // note it's not async, and works properly
6
+ // @ts-ignore
7
+ test: ({ buf, signal }?: { signal?: AbortSignal; buf?: ArrayBuffer }) => Generator<
8
+ {
9
+ progress: number;
10
+ aborted?: boolean;
11
+ },
12
+ string,
13
+ unknown
14
+ >;
15
+ // note it's not async, and works properly
16
+ returnYield: () => Generator<1 | 3 | 2, any, unknown>;
17
+ bidirectional: (prefix?: any) => Generator<string, string, number>;
18
+
19
+ error: () => AsyncGenerator<never, never, unknown>;
20
+ promise: () => Promise<{
21
+ test: string;
22
+ }>;
23
+ promiseError: () => Promise<never>;
24
+ setTimeout: ({ timeout }?: { timeout?: number }) => Promise<unknown>;
25
+ setInterval: ({ timeout }?: { timeout?: number }) => AsyncGenerator<any, never, unknown>;
26
+ };
27
+ stop: () => void;
28
+ } = wrpc().createResponder(self, {
4
29
  // note it's not async, and works properly
5
- test: function* ({ buf, signal }: { signal?: AbortSignal; buf?: ArrayBuffer } = {}) {
30
+ test: function* ({ buf, signal }: { signal?: AbortSignal; buf?: ArrayBuffer } = {}): Generator<
31
+ {
32
+ progress: number;
33
+ aborted?: boolean;
34
+ },
35
+ string,
36
+ unknown
37
+ > {
6
38
  yield { progress: 0 };
7
39
  yield { progress: 0.5 };
8
40
  yield { progress: 1, aborted: !!signal?.aborted };
9
41
  return 'foo';
10
42
  },
11
43
  // note it's not async, and works properly
12
- returnYield: function* () {
44
+ returnYield: function* (): Generator<1 | 3 | 2, any, unknown> {
13
45
  yield 1;
14
46
  yield 2;
15
47
  return yield 3;
@@ -23,13 +55,15 @@ export const responder = wrpc().createResponder(self, {
23
55
  return 'done';
24
56
  },
25
57
  // eslint-disable-next-line require-yield
26
- error: async function* () {
58
+ error: async function* (): AsyncGenerator<never, never, unknown> {
27
59
  throw new Error('Test');
28
60
  },
29
- promise: async function () {
61
+ promise: async function (): Promise<{
62
+ test: string;
63
+ }> {
30
64
  return { test: 'test' };
31
65
  },
32
- promiseError: async function () {
66
+ promiseError: async function (): Promise<never> {
33
67
  throw new Error('Test');
34
68
  },
35
69
  setTimeout: async ({ timeout = 1000 }: { timeout?: number } = {}) =>
package/src/core/wrpc.ts CHANGED
@@ -25,7 +25,7 @@ export type WorkerLike = {
25
25
  options?: { signal?: AbortSignal; once?: boolean },
26
26
  ) => void;
27
27
  removeEventListener: (event: string, listener: (e: any) => void) => void;
28
- };
28
+ } & any;
29
29
 
30
30
  export enum LogLevel {
31
31
  disabled = 0,
@@ -42,10 +42,10 @@ export function deriveController(signal?: AbortSignal): [AbortController, AbortS
42
42
  return [controller, AbortSignal.any([controller.signal, signal].filter(Boolean) as AbortSignal[])];
43
43
  }
44
44
 
45
- export function rejectOnSignal(promise: Promise<any>, signal: AbortSignal) {
45
+ export function rejectOnSignal(promise: Promise<any>, signal: AbortSignal): Promise<Event['data']> {
46
46
  return Promise.race([
47
47
  promise,
48
- new Promise<Event['data']>((resolve, reject) => {
48
+ new Promise((resolve, reject) => {
49
49
  signal.addEventListener('abort', () => reject('RaceAborted:' + signal.reason), { once: true, signal });
50
50
  }),
51
51
  ]);
@@ -56,7 +56,19 @@ export function rejectOnSignal(promise: Promise<any>, signal: AbortSignal) {
56
56
  export function wrpc({
57
57
  debug = LogLevel.disabled,
58
58
  name = (globalThis as any).importScripts ? 'RESPONDER' : 'CALLER',
59
- } = {}) {
59
+ }: {
60
+ debug?: LogLevel;
61
+ name?: string;
62
+ } = {}): {
63
+ createResponder: <T extends Responders>(
64
+ worker: WorkerLike,
65
+ responders: T,
66
+ ) => {
67
+ responders: T;
68
+ stop: () => void;
69
+ };
70
+ createCaller: <T extends Responders>(worker: WorkerLike, responders: T) => T;
71
+ } {
60
72
  // Logger
61
73
 
62
74
  function logger(type: string) {
@@ -130,7 +142,13 @@ export function wrpc({
130
142
  // Responder
131
143
 
132
144
  //TODO Name arg
133
- function createResponder<T extends Responders>(worker: WorkerLike, responders: T) {
145
+ function createResponder<T extends Responders>(
146
+ worker: WorkerLike,
147
+ responders: T,
148
+ ): {
149
+ responders: T;
150
+ stop: () => void;
151
+ } {
134
152
  const mainController = new AbortController();
135
153
 
136
154
  worker.addEventListener('messageerror', (e) => logError(LogLevel.error, null, 'MESSAGE ERROR', e), {
@@ -9,8 +9,8 @@ import defaultMenu from 'electron-default-menu';
9
9
  import Store from 'electron-store';
10
10
  import { checkForUpdates } from './updater.js';
11
11
 
12
- export const isDev = process.env['NODE_ENV'] === 'development';
13
- export const appPath = app.getAppPath();
12
+ export const isDev: boolean = process.env['NODE_ENV'] === 'development';
13
+ export const appPath: string = app.getAppPath();
14
14
 
15
15
  // See https://cs.chromium.org/chromium/src/net/base/net_error_list.h
16
16
  const FILE_NOT_FOUND = -6;
@@ -227,7 +227,7 @@ export function createWindow({
227
227
  app.on('activate', () => BrowserWindow.getAllWindows().length === 0 && !mainWindow && createWindow());
228
228
 
229
229
  return {
230
- get mainWindow() {
230
+ get mainWindow(): BrowserWindow | null {
231
231
  return mainWindow;
232
232
  },
233
233
  };
@@ -47,7 +47,7 @@ autoUpdater.on('update-downloaded', async () => {
47
47
  autoUpdater.quitAndInstall();
48
48
  });
49
49
 
50
- export function checkForUpdates(menuItem, focusedWindow, event) {
50
+ export function checkForUpdates(menuItem: any): void {
51
51
  updateButton = menuItem;
52
52
  updateButton.enabled = false;
53
53
  autoUpdater.checkForUpdates().catch((e) => console.error('Update error', e));
@@ -12,7 +12,7 @@ export async function generateImages({
12
12
  dmgBackgroundPsdPath: string;
13
13
  electronAssetsPath: string;
14
14
  webPublicPath: string;
15
- }) {
15
+ }): Promise<void> {
16
16
  const iconPsd = await psd.open(iconPsdPath);
17
17
  await iconPsd.image!.saveAsPng(path.join(electronAssetsPath, 'icon.png'));
18
18
 
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { GenericControl, GenericControlProps } from './genericControl';
3
3
  import { inputClasses } from '@mui/material/Input';
4
4
 
5
5
  export type FormControlFieldsetProps = GenericControlProps;
6
6
 
7
- export const FormControlFieldset: React.FC<FormControlFieldsetProps> = function FormControlFieldset({
7
+ export const FormControlFieldset: FC<FormControlFieldsetProps> = function FormControlFieldset({
8
8
  children,
9
9
  sx,
10
10
  ...props
@@ -1,7 +1,7 @@
1
- import * as React from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { default as InputLabel, InputLabelProps } from '@mui/material/InputLabel';
3
3
 
4
- export const FormLabelLegend: React.FC<InputLabelProps> = ({ children, ...props }) => {
4
+ export const FormLabelLegend: FC<InputLabelProps> = ({ children, ...props }) => {
5
5
  return (
6
6
  // sx={(theme) => theme.typography.caption}
7
7
  <InputLabel {...props} shrink={true} component={'legend' as any}>
@@ -1,10 +1,10 @@
1
- import * as React from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { FormControlProps, default as FormControl } from '@mui/material/FormControl';
3
3
  import { inputClasses } from '@mui/material/Input';
4
4
 
5
5
  export type GenericControlProps = FormControlProps & { children: any };
6
6
 
7
- export const GenericControl: React.FC<GenericControlProps> = ({ children, sx, ...props }) => (
7
+ export const GenericControl: FC<GenericControlProps> = ({ children, sx, ...props }) => (
8
8
  <FormControl
9
9
  variant="standard"
10
10
  sx={{
@@ -1,6 +1,6 @@
1
- import React from 'react';
1
+ import React, { FC } from 'react';
2
2
  import { default as Input, InputProps } from '@mui/material/Input';
3
3
 
4
- export const ReadOnly: React.FC<InputProps & { children: any }> = ({ children, inputProps, ...props }) => (
4
+ export const ReadOnly: FC<InputProps & { children: any }> = ({ children, inputProps, ...props }) => (
5
5
  <Input {...props} inputComponent={'div' as any} inputProps={{ ...inputProps, children }}></Input>
6
6
  );
@@ -1,7 +1,24 @@
1
1
  import { createMeasurer } from '../core/measure';
2
2
  import { PHASE_PRODUCTION_BUILD, PHASE_PRODUCTION_SERVER } from 'next/constants';
3
3
 
4
- export const isProd =
4
+ export const isProd: boolean =
5
5
  process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD || process.env.NEXT_PHASE === PHASE_PRODUCTION_SERVER;
6
6
 
7
- export const measurer = createMeasurer({ colors: isProd });
7
+ export const measurer: {
8
+ measure: (
9
+ what: string,
10
+ step: string,
11
+ supplemental?: string,
12
+ ...args: any[]
13
+ ) => {
14
+ done: (result?: string, ...args2: any[]) => void;
15
+ fail: (result?: string, ...args2: any[]) => void;
16
+ log: (...args2: any[]) => void;
17
+ };
18
+ important: (str: any) => any;
19
+ subject: (str: any) => any;
20
+ arg: (str: any) => any;
21
+ sup: (str: any) => any;
22
+ ok: (str: any) => any;
23
+ err: (str: any) => any;
24
+ } = createMeasurer({ colors: isProd });
@@ -1,12 +1,31 @@
1
1
  'use client';
2
2
 
3
- import React, { useLayoutEffect, useState } from 'react';
3
+ import React, { FC, JSX, useLayoutEffect, useState } from 'react';
4
4
 
5
- const DefaultOnSSR = () => <span />;
6
-
7
- // @see https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js
8
- // @see https://nextjs.org/docs/messages/react-hydration-error#solution-1-using-useeffect-to-run-on-the-client-only
9
- export function NoSSR({ children, onSSR = <DefaultOnSSR /> }) {
5
+ /**
6
+ * Prefer using Next.js `dynamic()` import with `ssr: false` because this will also remove import from server bundle.
7
+ *
8
+ * ```tsx
9
+ * 'use client';
10
+ *
11
+ * import React from 'react';
12
+ * import dynamic from 'next/dynamic';
13
+ *
14
+ * const PageClient = dynamic(() => import('./pageClient'), { ssr: false });
15
+ *
16
+ * export default function Page() {
17
+ * return (
18
+ * <PageClient />
19
+ * );
20
+ * }
21
+ * ```
22
+ *
23
+ * In other cases this component can be used to just prevent server rendering.
24
+ *
25
+ * @see https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js
26
+ * @see https://nextjs.org/docs/messages/react-hydration-error#solution-1-using-useeffect-to-run-on-the-client-only
27
+ */
28
+ export const NoSSR: FC<{ children: any; onSSR?: JSX.Element }> = function NoSSR({ children, onSSR = null }): any {
10
29
  const [canRender, setCanRender] = useState(false);
11
30
 
12
31
  useLayoutEffect(() => {
@@ -14,4 +33,4 @@ export function NoSSR({ children, onSSR = <DefaultOnSSR /> }) {
14
33
  }, []);
15
34
 
16
35
  return canRender ? children : onSSR;
17
- }
36
+ };
@@ -6,7 +6,18 @@ import { z } from 'zod';
6
6
 
7
7
  const FORM_DEBUG = process.env.NEXT_PUBLIC_FORM_DEBUG === 'true';
8
8
 
9
- export function createClient<S extends z.ZodObject<any>>(schema: S) {
9
+ export function createClient<S extends z.ZodObject<any>>(
10
+ schema: S,
11
+ ): {
12
+ useValidation: (
13
+ actionFn: (data: FormData) => Promise<Validation<S>>,
14
+ initialData?: MaybeTypeOf<S>,
15
+ ) => [state: Validation<S>, dispatch: (payload: FormData) => void, isPending: boolean];
16
+ useValidationTransition: (
17
+ actionFn: (data: FormData) => Promise<Validation<S>>,
18
+ initialData?: MaybeTypeOf<S>,
19
+ ) => [Validation<S>, (formData: FormData) => Promise<Validation<S>>, boolean];
20
+ } {
10
21
  const { validate } = create(schema);
11
22
 
12
23
  function useValidationCallback(
@@ -29,7 +40,7 @@ export function createClient<S extends z.ZodObject<any>>(schema: S) {
29
40
  function useValidation(
30
41
  actionFn: (data: FormData) => Promise<Validation<S>>,
31
42
  initialData: MaybeTypeOf<S> = {} as MaybeTypeOf<S>,
32
- ) {
43
+ ): [state: Validation<S>, dispatch: (payload: FormData) => void, isPending: boolean] {
33
44
  const cb = useValidationCallback(actionFn);
34
45
 
35
46
  return useActionState<Validation<S>, FormData>(async (_, data) => cb(data), {
@@ -1,10 +1,10 @@
1
1
  import { typeToFlattenedError, z, SafeParseReturnType, TypeOf } from 'zod';
2
- import { createContext, useContext, useMemo } from 'react';
2
+ import { Context, createContext, useContext, useMemo, JSX, FC, memo } from 'react';
3
3
  import clsx from 'clsx';
4
4
 
5
5
  const nonEmpty = 'This field cannot be empty';
6
6
 
7
- export const stringRequired = () => z.string({ required_error: nonEmpty }).min(1, nonEmpty);
7
+ export const stringRequired = (): z.ZodString => z.string({ required_error: nonEmpty }).min(1, nonEmpty);
8
8
  export const maxLength = (schema: z.ZodString): number => schema.maxLength || 0;
9
9
  export const minLength = (schema: z.ZodString): number => schema.minLength || 0;
10
10
  export const isRequired = (schema: z.ZodString): boolean => minLength(schema) > 0;
@@ -25,24 +25,65 @@ export type Validation<S extends ZodObject> =
25
25
  errors?: Errors<S>;
26
26
  };
27
27
 
28
- export const FormContext = createContext<{
28
+ export const FormContext: Context<{
29
29
  schema: ZodObject;
30
- }>(null as never);
30
+ }> = createContext(null as never);
31
31
 
32
- export const Form = <S extends ZodObject>({ schema, children }: { schema: S; children: any }) => {
32
+ export interface FormProps<S extends ZodObject> {
33
+ schema: S;
34
+ children: any;
35
+ }
36
+
37
+ export const Form: FC<FormProps<any>> = memo(function Form({ schema, children }) {
33
38
  const value = useMemo(() => ({ schema }), [schema]);
34
39
  return <FormContext.Provider value={value}>{children}</FormContext.Provider>;
35
- };
40
+ });
36
41
 
37
42
  const getShape = <S extends ZodObject>(schema: S) =>
38
43
  (schema as z.ZodObject<any>).shape || (schema as z.ZodEffects<z.ZodObject<any>>).sourceType().shape;
39
44
 
40
- export function create<S extends ZodObject>(schema: S) {
45
+ export function create<S extends ZodObject>(
46
+ schema: S,
47
+ ): {
48
+ register: (
49
+ name: keyof TypeOf<S>,
50
+ data?: MaybeTypeOf<S>,
51
+ errors?: Errors<S>,
52
+ mui?: boolean,
53
+ ) => {
54
+ label?: any;
55
+ helperText?: string;
56
+ error?: boolean;
57
+ name: keyof z.TypeOf<S>;
58
+ id: keyof z.TypeOf<S>;
59
+ required: boolean;
60
+ maxLength: number;
61
+ type: string;
62
+ defaultValue?: Partial<z.TypeOf<S>>[keyof z.TypeOf<S>];
63
+ };
64
+ validate: (formData: FormData) => Validation<S>;
65
+ validationError: (data: MaybeTypeOf<S>, errors: Errors<S>) => Validation<S>;
66
+ } {
41
67
  if (!getShape(schema)) {
42
68
  throw new Error('Invalid schema: only z.object() or z.object().refine() are supported');
43
69
  }
44
70
 
45
- function register(name: keyof TypeOf<S>, data?: MaybeTypeOf<S>, errors?: Errors<S>, mui: boolean = false) {
71
+ function register(
72
+ name: keyof TypeOf<S>,
73
+ data?: MaybeTypeOf<S>,
74
+ errors?: Errors<S>,
75
+ mui: boolean = false,
76
+ ): {
77
+ label?: any;
78
+ helperText?: string;
79
+ error?: boolean;
80
+ name: keyof z.TypeOf<S>;
81
+ id: keyof z.TypeOf<S>;
82
+ required: boolean;
83
+ maxLength: number;
84
+ type: string;
85
+ defaultValue?: Partial<z.TypeOf<S>>[keyof z.TypeOf<S>];
86
+ } {
46
87
  const field = getShape(schema)[name];
47
88
  return {
48
89
  name,
@@ -87,7 +128,17 @@ export function create<S extends ZodObject>(schema: S) {
87
128
  return { register, validate, validationError };
88
129
  }
89
130
 
90
- function Field<S extends ZodObject>({
131
+ interface FieldProps<S extends ZodObject> {
132
+ children?: any;
133
+ name: keyof TypeOf<S>;
134
+ errors?: Validation<S>['errors'];
135
+ hint?: string;
136
+ className?: string;
137
+ labelProps?: any;
138
+ [key: string]: any;
139
+ }
140
+
141
+ export const Field: FC<FieldProps<any>> = memo(function Field({
91
142
  children,
92
143
  name,
93
144
  errors,
@@ -95,13 +146,6 @@ function Field<S extends ZodObject>({
95
146
  className,
96
147
  labelProps,
97
148
  ...props
98
- }: {
99
- children?: any;
100
- name: keyof TypeOf<S>;
101
- errors?: Validation<S>['errors'];
102
- hint?: string;
103
- className?: string;
104
- labelProps?: any;
105
149
  }) {
106
150
  const { schema } = useContext(FormContext);
107
151
  const { description } = getShape(schema)[name];
@@ -122,8 +166,13 @@ function Field<S extends ZodObject>({
122
166
  ))}
123
167
  </div>
124
168
  );
169
+ });
170
+
171
+ export interface HintProps {
172
+ children: any;
173
+ error?: boolean;
125
174
  }
126
175
 
127
- export function Hint({ children, error }: { children: any; error?: boolean }) {
176
+ export const Hint: FC<HintProps> = memo(function Hint({ children, error }) {
128
177
  return <div className={`hint ${error ? 'hint-error' : ''}`}>{children}</div>;
129
- }
178
+ });
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useEffect, createContext, useMemo, useState, Dispatch, SetStateAction, useContext } from 'react';
3
+ import { useEffect, createContext, useMemo, useState, Dispatch, SetStateAction, useContext, FC, Context } from 'react';
4
4
 
5
5
  const isCtrlOrMeta = (e: KeyboardEvent) => e.metaKey || e.ctrlKey;
6
6
 
@@ -8,12 +8,17 @@ const EVENT = 'keydown';
8
8
 
9
9
  export type Hotkeys = Record<KeyboardEvent['code'], (e: KeyboardEvent) => void>;
10
10
 
11
- export const HotkeysContext = createContext<{
11
+ export type HotkeyContextType = {
12
+ enabled: boolean;
13
+ setEnabled: Dispatch<SetStateAction<boolean>>;
14
+ };
15
+
16
+ export const HotkeysContext: Context<HotkeyContextType> = createContext<{
12
17
  enabled: boolean;
13
18
  setEnabled: Dispatch<SetStateAction<boolean>>;
14
19
  }>(null as never);
15
20
 
16
- export const HotkeysProvider = ({ children }) => {
21
+ export const HotkeysProvider: FC<any> = ({ children }) => {
17
22
  const [enabled, setEnabled] = useState(true);
18
23
 
19
24
  const control = useMemo(() => ({ enabled, setEnabled }), [enabled, setEnabled]);
@@ -21,7 +26,7 @@ export const HotkeysProvider = ({ children }) => {
21
26
  return <HotkeysContext.Provider value={control}>{children}</HotkeysContext.Provider>;
22
27
  };
23
28
 
24
- export const useHotkeys = (hotkeys: Hotkeys) => {
29
+ export const useHotkeys = (hotkeys: Hotkeys): void => {
25
30
  const { enabled } = useContext(HotkeysContext);
26
31
 
27
32
  useEffect(() => {
@@ -1,10 +1,15 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
2
 
3
3
  export function useFetcher<T = any>(
4
- cb,
4
+ cb: any,
5
5
 
6
6
  { fetchOnMount = false, onError }: { fetchOnMount?: boolean; onError?: (e: Error) => void } = {},
7
- ) {
7
+ ): {
8
+ loading: boolean;
9
+ error: Error | null;
10
+ data: T | null;
11
+ trigger: (...args: any[]) => Promise<any>;
12
+ } {
8
13
  const [loading, setLoading] = useState(fetchOnMount);
9
14
  const [error, setError] = useState<Error | null>(null);
10
15
  const [data, setData] = useState<T | null>(null);
@@ -12,7 +17,7 @@ export function useFetcher<T = any>(
12
17
  const isMounted = useRef(false);
13
18
 
14
19
  const trigger = useCallback(
15
- async (...args) => {
20
+ async (...args: any[]): Promise<any> => {
16
21
  try {
17
22
  setLoading(true);
18
23
  setError(null);
@@ -8,7 +8,7 @@ import * as Sharing from 'expo-sharing';
8
8
  * @param fileName
9
9
  * @returns {Promise<void>}
10
10
  */
11
- export const shareDialog = async (base64, fileName) => {
11
+ export const shareDialog = async (base64: string, fileName: string): Promise<void> => {
12
12
  const path = `${FileSystem.documentDirectory}/${fileName}`;
13
13
 
14
14
  try {
@@ -1,8 +1,8 @@
1
1
  import * as Updates from 'expo-updates';
2
- import { useEffect, useState } from 'react';
2
+ import { FC, useEffect, useState } from 'react';
3
3
  import { Text } from 'react-native';
4
4
 
5
- export function Update({ children }) {
5
+ export const Update: FC<any> = function Update({ children }) {
6
6
  //FIXME useUpdates https://blog.expo.dev/feature-preview-updates-js-api-for-expo-updates-3b92beb40dab
7
7
  const [updating, setUpdating] = useState(true);
8
8
 
@@ -37,4 +37,4 @@ export function Update({ children }) {
37
37
  }
38
38
 
39
39
  return children;
40
- }
40
+ };
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import { AppState } from 'react-native';
3
3
 
4
- export function useAppState() {
4
+ export function useAppState(): 'active' | 'background' | 'inactive' | 'unknown' | 'extension' {
5
5
  const [appState, setAppState] = useState(AppState.currentState);
6
6
 
7
7
  useEffect(() => {
@@ -1,6 +1,6 @@
1
- import React from 'react';
1
+ import React, { FC } from 'react';
2
2
 
3
- export const Fullpage = ({ divRef = null, className = '', children, ...props }) => (
3
+ export const Fullpage: FC<any> = ({ divRef = null, className = '', children, ...props }) => (
4
4
  <div
5
5
  ref={divRef}
6
6
  {...props}