@pistonite/pure 0.28.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +23 -4
- package/dist/_dts_/src/log/index.d.ts +37 -0
- package/dist/_dts_/src/log/index.d.ts.map +1 -0
- package/dist/_dts_/src/log/logger.d.ts +27 -0
- package/dist/_dts_/src/log/logger.d.ts.map +1 -0
- package/dist/_dts_/src/memory/cell.d.ts +25 -0
- package/dist/_dts_/src/memory/cell.d.ts.map +1 -0
- package/dist/_dts_/src/memory/emp.d.ts +87 -0
- package/dist/_dts_/src/memory/emp.d.ts.map +1 -0
- package/dist/_dts_/src/memory/idgen.d.ts +18 -0
- package/dist/_dts_/src/memory/idgen.d.ts.map +1 -0
- package/dist/_dts_/src/memory/index.d.ts +10 -0
- package/dist/_dts_/src/memory/index.d.ts.map +1 -0
- package/dist/_dts_/src/memory/persist.d.ts +38 -0
- package/dist/_dts_/src/memory/persist.d.ts.map +1 -0
- package/dist/_dts_/src/result/index.d.ts +191 -0
- package/dist/_dts_/src/result/index.d.ts.map +1 -0
- package/dist/_dts_/src/sync/RwLock.d.ts +30 -0
- package/dist/_dts_/src/sync/RwLock.d.ts.map +1 -0
- package/dist/_dts_/src/sync/batch.d.ts +112 -0
- package/dist/_dts_/src/sync/batch.d.ts.map +1 -0
- package/dist/_dts_/src/sync/capture.d.ts +11 -0
- package/dist/_dts_/src/sync/capture.d.ts.map +1 -0
- package/dist/_dts_/src/sync/debounce.d.ts +105 -0
- package/dist/_dts_/src/sync/debounce.d.ts.map +1 -0
- package/dist/_dts_/src/sync/index.d.ts +15 -0
- package/dist/_dts_/src/sync/index.d.ts.map +1 -0
- package/dist/_dts_/src/sync/latest.d.ts +86 -0
- package/dist/_dts_/src/sync/latest.d.ts.map +1 -0
- package/dist/_dts_/src/sync/mutex.d.ts +14 -0
- package/dist/_dts_/src/sync/mutex.d.ts.map +1 -0
- package/dist/_dts_/src/sync/once.d.ts +84 -0
- package/dist/_dts_/src/sync/once.d.ts.map +1 -0
- package/dist/_dts_/src/sync/serial.d.ts +162 -0
- package/dist/_dts_/src/sync/serial.d.ts.map +1 -0
- package/dist/_dts_/src/sync/util.d.ts +19 -0
- package/dist/_dts_/src/sync/util.d.ts.map +1 -0
- package/dist/log/index.js +57 -0
- package/dist/log/index.js.map +1 -0
- package/dist/memory/index.js +92 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/result/index.js +29 -0
- package/dist/result/index.js.map +1 -0
- package/dist/sync/index.js +252 -0
- package/dist/sync/index.js.map +1 -0
- package/package.json +22 -13
- package/src/env.d.ts +1 -0
- package/src/log/index.ts +36 -11
- package/src/log/logger.ts +93 -115
- package/src/memory/cell.ts +21 -11
- package/src/memory/emp.ts +34 -23
- package/src/memory/idgen.test.ts +1 -1
- package/src/memory/index.ts +1 -4
- package/src/memory/persist.ts +9 -12
- package/src/result/index.ts +12 -4
- package/src/sync/batch.test.ts +1 -1
- package/src/sync/batch.ts +12 -17
- package/src/sync/capture.ts +2 -0
- package/src/sync/debounce.test.ts +1 -1
- package/src/sync/debounce.ts +12 -15
- package/src/sync/index.ts +2 -3
- package/src/sync/latest.test.ts +1 -1
- package/src/sync/latest.ts +19 -16
- package/src/sync/once.test.ts +1 -1
- package/src/sync/once.ts +13 -8
- package/src/sync/serial.test.ts +1 -1
- package/src/sync/serial.ts +14 -12
- package/src/sync/util.ts +2 -2
- package/src/fs/FsError.ts +0 -55
- package/src/fs/FsFile.ts +0 -67
- package/src/fs/FsFileImpl.ts +0 -219
- package/src/fs/FsFileMgr.ts +0 -29
- package/src/fs/FsFileStandalone.ts +0 -21
- package/src/fs/FsFileStandaloneImplFileAPI.ts +0 -54
- package/src/fs/FsFileStandaloneImplHandleAPI.ts +0 -147
- package/src/fs/FsFileSystem.ts +0 -71
- package/src/fs/FsFileSystemInternal.ts +0 -30
- package/src/fs/FsImplEntryAPI.ts +0 -149
- package/src/fs/FsImplFileAPI.ts +0 -116
- package/src/fs/FsImplHandleAPI.ts +0 -199
- package/src/fs/FsOpen.ts +0 -271
- package/src/fs/FsOpenFile.ts +0 -256
- package/src/fs/FsPath.ts +0 -137
- package/src/fs/FsSave.ts +0 -216
- package/src/fs/FsSupportStatus.ts +0 -87
- package/src/fs/index.ts +0 -123
- package/src/log/internal.ts +0 -14
- package/src/memory/async_erc.ts +0 -186
- package/src/memory/erc.test.ts +0 -258
- package/src/memory/erc.ts +0 -320
- package/src/pref/dark.ts +0 -151
- package/src/pref/device.ts +0 -118
- package/src/pref/index.ts +0 -13
- package/src/pref/inject_style.ts +0 -22
- package/src/pref/locale.ts +0 -296
package/src/pref/locale.ts
DELETED
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
import { persist } from "../memory/persist.ts";
|
|
2
|
-
import type { Result } from "../result/index.ts";
|
|
3
|
-
import { serial } from "../sync/serial.ts";
|
|
4
|
-
|
|
5
|
-
let supportedLocales: readonly string[] = [];
|
|
6
|
-
let defaultLocale: string = "";
|
|
7
|
-
let settingLocale: string = ""; // if locale is being set (setLocale called)
|
|
8
|
-
let onBeforeChangeHook: (newLocale: string) => Promise<Result<void, "cancel">> = () => {
|
|
9
|
-
return Promise.resolve({} as Result<void, "cancel">);
|
|
10
|
-
};
|
|
11
|
-
const locale = persist<string>({
|
|
12
|
-
initial: "",
|
|
13
|
-
key: "Pure.Locale",
|
|
14
|
-
storage: localStorage,
|
|
15
|
-
serialize: (value) => value,
|
|
16
|
-
deserialize: (value) => {
|
|
17
|
-
const supported = convertToSupportedLocale(value);
|
|
18
|
-
return supported || null;
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Use browser API to guess user's preferred locale
|
|
24
|
-
*/
|
|
25
|
-
export const getPreferredLocale = (): string => {
|
|
26
|
-
if (globalThis.Intl) {
|
|
27
|
-
try {
|
|
28
|
-
return globalThis.Intl.NumberFormat().resolvedOptions().locale;
|
|
29
|
-
} catch {
|
|
30
|
-
// ignore
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (globalThis.navigator?.languages) {
|
|
34
|
-
return globalThis.navigator.languages[0];
|
|
35
|
-
}
|
|
36
|
-
return "";
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type LocaleOptions<TLocale extends string> = {
|
|
40
|
-
/**
|
|
41
|
-
* List of supported locale or languages.
|
|
42
|
-
* These can be full locale strings like "en-US" or just languages like "en"
|
|
43
|
-
*/
|
|
44
|
-
supported: readonly TLocale[];
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* The default locale if the user's preferred locale is not supported.
|
|
48
|
-
* This must be one of the items in `supported`.
|
|
49
|
-
*/
|
|
50
|
-
default: TLocale;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Initial value for locale
|
|
54
|
-
*
|
|
55
|
-
* If not set, it will default to calling `getPreferredLocale()`,
|
|
56
|
-
* which is based on the browser's language settings.
|
|
57
|
-
*
|
|
58
|
-
* If `persist` is `true`, it will also check the value from localStorage
|
|
59
|
-
*
|
|
60
|
-
* If the initial value is not supported, it will default to the default locale
|
|
61
|
-
*/
|
|
62
|
-
initial?: TLocale;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Persist the locale preference to localStorage
|
|
66
|
-
*/
|
|
67
|
-
persist?: boolean;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Hook to be called by `setLocale`, but before setting the locale and thus notifying
|
|
71
|
-
* the subscribers.
|
|
72
|
-
*
|
|
73
|
-
* Internally, this is synchronized by the `serial` function, which means
|
|
74
|
-
* if another `setLocale` is called before the hook finishes, the set operation of the current
|
|
75
|
-
* call will not happen and the locale will only be set after the hook finishes in the new call.
|
|
76
|
-
*
|
|
77
|
-
* If there are race conditions in the hook, `checkCancel` should be used after any async operations,
|
|
78
|
-
* which will throw an error if another call happened.
|
|
79
|
-
*
|
|
80
|
-
* Note that this hook will not be called during initialization.
|
|
81
|
-
*/
|
|
82
|
-
onBeforeChange?: (newLocale: string, checkCancel: () => void) => void | Promise<void>;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Initialize Locale utilities
|
|
87
|
-
*
|
|
88
|
-
* `initLocale` must be called before using the other functions.
|
|
89
|
-
*
|
|
90
|
-
* ```typescript
|
|
91
|
-
* import { initLocale } from "@pistonite/pure/pref";
|
|
92
|
-
*
|
|
93
|
-
* initLocale({
|
|
94
|
-
* // required
|
|
95
|
-
* supported: ["en", "zh-CN", "zh-TW"] as const,
|
|
96
|
-
* default: "en",
|
|
97
|
-
*
|
|
98
|
-
* // optional
|
|
99
|
-
* persist: true, // save to localStorage
|
|
100
|
-
* initial: "en-US", // initial value, instead of detecting
|
|
101
|
-
* });
|
|
102
|
-
* ```
|
|
103
|
-
*
|
|
104
|
-
* ## Connecting with i18next
|
|
105
|
-
* The `@pistonite/pure-i18next` package provides additional wrapper
|
|
106
|
-
* for connecting with i18next. See the documentation there for more details.
|
|
107
|
-
* You will use `initLocaleWithI18next` instead of `initLocale`.
|
|
108
|
-
*
|
|
109
|
-
* ## Use with React
|
|
110
|
-
* A React hook is provided in the [`pure-react`](https://jsr.io/@pistonite/pure-react/doc/pref) package
|
|
111
|
-
* to get the current locale from React components.
|
|
112
|
-
*
|
|
113
|
-
* Changing the locale from React components is the same as from outside React,
|
|
114
|
-
* with `setLocale` or `i18next.changeLanguage`, depending on your setup.
|
|
115
|
-
*/
|
|
116
|
-
export const initLocale = <TLocale extends string>(options: LocaleOptions<TLocale>): void => {
|
|
117
|
-
if (options.onBeforeChange) {
|
|
118
|
-
const onBeforeChange = options.onBeforeChange;
|
|
119
|
-
onBeforeChangeHook = serial({
|
|
120
|
-
fn: (checkCancel) => async (newLocale: string) => {
|
|
121
|
-
await onBeforeChange(newLocale, checkCancel);
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
let _locale = "";
|
|
127
|
-
supportedLocales = options.supported;
|
|
128
|
-
if (options.initial) {
|
|
129
|
-
_locale = options.initial;
|
|
130
|
-
} else {
|
|
131
|
-
_locale = convertToSupportedLocale(getPreferredLocale()) || options.default;
|
|
132
|
-
}
|
|
133
|
-
defaultLocale = options.default;
|
|
134
|
-
if (options.persist) {
|
|
135
|
-
locale.init(_locale);
|
|
136
|
-
} else {
|
|
137
|
-
locale.disable();
|
|
138
|
-
locale.set(_locale);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Clear the locale preference previously presisted to localStorage
|
|
144
|
-
*
|
|
145
|
-
* If you are doing this, you should probably call `setLocale`
|
|
146
|
-
* or `i18next.changeLanguage` (depending on your setup) immediately
|
|
147
|
-
* before this with `convertToSupportedLocaleOrDefault(getPreferredLocale())`
|
|
148
|
-
* so the current locale is set to user's preferred locale.
|
|
149
|
-
*
|
|
150
|
-
* Note if `persist` is `true` when initializing,
|
|
151
|
-
* subsequence `setLocale` calls will still persist the value.
|
|
152
|
-
*/
|
|
153
|
-
export const clearPersistedLocalePreference = (): void => {
|
|
154
|
-
locale.clear();
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
/** Get the current selected locale */
|
|
158
|
-
export const getLocale = (): string => locale.get();
|
|
159
|
-
|
|
160
|
-
/** Get the default locale when initialized */
|
|
161
|
-
export const getDefaultLocale = (): string => {
|
|
162
|
-
return defaultLocale;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Set the selected locale
|
|
167
|
-
*
|
|
168
|
-
* Returns `false` if the locale is not supported.
|
|
169
|
-
*
|
|
170
|
-
* onBeforeChange hook is called regardless of if the new locale
|
|
171
|
-
* is the same as the current locale. If the hook is asynchronous and
|
|
172
|
-
* another `setLocale` is called before it finishes, the locale will not be set
|
|
173
|
-
* with the current call and will be set with the new call instead.
|
|
174
|
-
*/
|
|
175
|
-
export const setLocale = (newLocale: string): boolean => {
|
|
176
|
-
const supported = convertToSupportedLocale(newLocale);
|
|
177
|
-
if (!supported) {
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
if (supported === settingLocale) {
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
settingLocale = supported;
|
|
184
|
-
void onBeforeChangeHook(supported).then((result) => {
|
|
185
|
-
if (result.err) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
settingLocale = "";
|
|
189
|
-
locale.set(supported);
|
|
190
|
-
});
|
|
191
|
-
return true;
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Convert a locale/language to a supported locale/language
|
|
196
|
-
*
|
|
197
|
-
* Returns `undefined` if no supported locale is found
|
|
198
|
-
*
|
|
199
|
-
* # Example
|
|
200
|
-
* It will first try to find an exact match for a locale (not language).
|
|
201
|
-
* If not found, it will try:
|
|
202
|
-
* - the first supported locale with a matching language
|
|
203
|
-
* - the first supported language
|
|
204
|
-
* ```typescript
|
|
205
|
-
* import { convertToSupportedLocale } from "@pistonite/pure/pref";
|
|
206
|
-
*
|
|
207
|
-
* // suppose supported locales are ["en", "zh", "zh-CN"]
|
|
208
|
-
* console.log(convertToSupportedLocale("en")); // "en"
|
|
209
|
-
* console.log(convertToSupportedLocale("en-US")); // "en"
|
|
210
|
-
* console.log(convertToSupportedLocale("zh")); // "zh-CN"
|
|
211
|
-
* console.log(convertToSupportedLocale("zh-CN")); // "zh-CN"
|
|
212
|
-
* console.log(convertToSupportedLocale("zh-TW")); // "zh"
|
|
213
|
-
* console.log(convertToSupportedLocale("es")); // undefined
|
|
214
|
-
* ```
|
|
215
|
-
*/
|
|
216
|
-
export const convertToSupportedLocale = (newLocale: string): string | undefined => {
|
|
217
|
-
return convertToSupportedLocaleIn(newLocale, supportedLocales);
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* See {@link convertToSupportedLocale}
|
|
222
|
-
*
|
|
223
|
-
* This takes the supported locale array so it can be used
|
|
224
|
-
* outside of the locale system
|
|
225
|
-
*/
|
|
226
|
-
export const convertToSupportedLocaleIn = (
|
|
227
|
-
newLocale: string,
|
|
228
|
-
supportedLocalesToCheck: string[] | readonly string[],
|
|
229
|
-
): string | undefined => {
|
|
230
|
-
if (supportedLocalesToCheck.includes(newLocale)) {
|
|
231
|
-
return newLocale;
|
|
232
|
-
}
|
|
233
|
-
const language = newLocale.split("-", 2)[0];
|
|
234
|
-
const len = supportedLocalesToCheck.length;
|
|
235
|
-
for (let i = 0; i < len; i++) {
|
|
236
|
-
if (supportedLocalesToCheck[i].startsWith(language)) {
|
|
237
|
-
return supportedLocalesToCheck[i];
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return undefined;
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Convert a locale/language to a supported locale/language,
|
|
245
|
-
* or return the default locale if not found.
|
|
246
|
-
*
|
|
247
|
-
* This is a thin wrapper for `convertToSupportedLocale`.
|
|
248
|
-
* See that function for more details.
|
|
249
|
-
*/
|
|
250
|
-
export const convertToSupportedLocaleOrDefault = (newLocale: string): string => {
|
|
251
|
-
return convertToSupportedLocale(newLocale) || defaultLocale;
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Add a subscriber to be notified when the locale changes.
|
|
256
|
-
* Returns a function to remove the subscriber
|
|
257
|
-
*
|
|
258
|
-
* If `notifyImmediately` is `true`, the subscriber will be called immediately with the current locale.
|
|
259
|
-
* Note that it's not guaranteed that the new locale is ready when the subscriber is notified.
|
|
260
|
-
* Any async operations such as loading the language files should be done in the
|
|
261
|
-
* `onBeforeChange` hook if the subscribers need to wait for it.
|
|
262
|
-
*/
|
|
263
|
-
export const addLocaleSubscriber = (
|
|
264
|
-
fn: (locale: string) => void,
|
|
265
|
-
notifyImmediately?: boolean,
|
|
266
|
-
): (() => void) => {
|
|
267
|
-
return locale.subscribe(fn, notifyImmediately);
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const localizedLanguageNames = new Map();
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Get the localized name of a language using `Intl.DisplayNames`.
|
|
274
|
-
*
|
|
275
|
-
* The results are interanlly cached, so you don't need to cache this yourself.
|
|
276
|
-
*/
|
|
277
|
-
export const getLocalizedLanguageName = (language: string): string => {
|
|
278
|
-
if (language === "zh" || language === "zh-CN") {
|
|
279
|
-
return "\u7b80\u4f53\u4e2d\u6587";
|
|
280
|
-
}
|
|
281
|
-
if (language === "zh-TW") {
|
|
282
|
-
return "\u7e41\u9ad4\u4e2d\u6587";
|
|
283
|
-
}
|
|
284
|
-
if (localizedLanguageNames.has(language)) {
|
|
285
|
-
return localizedLanguageNames.get(language);
|
|
286
|
-
}
|
|
287
|
-
const languageWithoutLocale = language.split("-")[0];
|
|
288
|
-
const localized = new Intl.DisplayNames([language], {
|
|
289
|
-
type: "language",
|
|
290
|
-
}).of(languageWithoutLocale);
|
|
291
|
-
localizedLanguageNames.set(language, localized);
|
|
292
|
-
return localized || language;
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
/** Get the array of supported locales passed to init */
|
|
296
|
-
export const getSupportedLocales = (): readonly string[] => supportedLocales;
|