@take-out/helpers 0.2.1 → 0.2.3
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/package.json +1 -1
- package/types/array/getRandomItem.d.ts +0 -3
- package/types/array/getRandomItem.d.ts.map +0 -11
- package/types/array/takeLast.d.ts +0 -3
- package/types/array/takeLast.d.ts.map +0 -11
- package/types/array/uniqBy.d.ts +0 -12
- package/types/array/uniqBy.d.ts.map +0 -11
- package/types/assert.d.ts +0 -6
- package/types/assert.d.ts.map +0 -11
- package/types/async/abortable.d.ts +0 -10
- package/types/async/abortable.d.ts.map +0 -11
- package/types/async/asyncContext.d.ts +0 -8
- package/types/async/asyncContext.d.ts.map +0 -11
- package/types/async/asyncContext.native.d.ts +0 -8
- package/types/async/asyncContext.native.d.ts.map +0 -11
- package/types/async/idle.d.ts +0 -8
- package/types/async/idle.d.ts.map +0 -11
- package/types/async/interval.d.ts +0 -3
- package/types/async/interval.d.ts.map +0 -11
- package/types/async/isAborted.d.ts +0 -3
- package/types/async/isAborted.d.ts.map +0 -11
- package/types/async/sleep.d.ts +0 -3
- package/types/async/sleep.d.ts.map +0 -11
- package/types/async/useAsync.d.ts +0 -3
- package/types/async/useAsync.d.ts.map +0 -11
- package/types/async/useAsyncEffect.d.ts +0 -12
- package/types/async/useAsyncEffect.d.ts.map +0 -11
- package/types/async/useLazyMount.d.ts +0 -9
- package/types/async/useLazyMount.d.ts.map +0 -11
- package/types/async/useLazyValue.d.ts +0 -6
- package/types/async/useLazyValue.d.ts.map +0 -11
- package/types/browser/clearIndexedDB.d.ts +0 -3
- package/types/browser/clearIndexedDB.d.ts.map +0 -11
- package/types/browser/isActiveElementFormField.d.ts +0 -3
- package/types/browser/isActiveElementFormField.d.ts.map +0 -11
- package/types/browser/openPopup.d.ts +0 -3
- package/types/browser/openPopup.d.ts.map +0 -11
- package/types/client-only.d.ts +0 -2
- package/types/client-only.d.ts.map +0 -11
- package/types/clipboard/clipboard.d.ts +0 -3
- package/types/clipboard/clipboard.d.ts.map +0 -11
- package/types/clipboard/clipboard.native.d.ts +0 -3
- package/types/clipboard/clipboard.native.d.ts.map +0 -11
- package/types/color/extractOpacityFromColor.d.ts +0 -3
- package/types/color/extractOpacityFromColor.d.ts.map +0 -11
- package/types/color/generateColors.d.ts +0 -11
- package/types/color/generateColors.d.ts.map +0 -11
- package/types/color/lum.d.ts +0 -3
- package/types/color/lum.d.ts.map +0 -11
- package/types/color/toHex.d.ts +0 -4
- package/types/color/toHex.d.ts.map +0 -11
- package/types/constants.d.ts +0 -10
- package/types/constants.d.ts.map +0 -17
- package/types/debug/debugLog.d.ts +0 -11
- package/types/debug/debugLog.d.ts.map +0 -11
- package/types/debug/debugUseState.d.ts +0 -3
- package/types/debug/debugUseState.d.ts.map +0 -11
- package/types/emitter.d.ts +0 -77
- package/types/emitter.d.ts.map +0 -11
- package/types/ensure/ensure.d.ts +0 -6
- package/types/ensure/ensure.d.ts.map +0 -11
- package/types/ensure/ensureOne.d.ts +0 -3
- package/types/ensure/ensureOne.d.ts.map +0 -11
- package/types/error/errors.d.ts +0 -8
- package/types/error/errors.d.ts.map +0 -11
- package/types/function/emptyFn.d.ts +0 -3
- package/types/function/emptyFn.d.ts.map +0 -11
- package/types/function/identityFn.d.ts +0 -3
- package/types/function/identityFn.d.ts.map +0 -11
- package/types/function/throttle.d.ts +0 -23
- package/types/function/throttle.d.ts.map +0 -11
- package/types/global/globalEffect.d.ts +0 -3
- package/types/global/globalEffect.d.ts.map +0 -11
- package/types/global/globalValue.d.ts +0 -24
- package/types/global/globalValue.d.ts.map +0 -11
- package/types/index.d.ts +0 -78
- package/types/index.d.ts.map +0 -11
- package/types/number/formatNumber.d.ts +0 -13
- package/types/number/formatNumber.d.ts.map +0 -11
- package/types/object/decorateObject.d.ts +0 -3
- package/types/object/decorateObject.d.ts.map +0 -11
- package/types/object/isEqualDeep.d.ts +0 -6
- package/types/object/isEqualDeep.d.ts.map +0 -14
- package/types/object/isEqualIdentity.d.ts +0 -3
- package/types/object/isEqualIdentity.d.ts.map +0 -11
- package/types/object/isEqualJSON.d.ts +0 -3
- package/types/object/isEqualJSON.d.ts.map +0 -11
- package/types/object/isEqualNever.d.ts +0 -3
- package/types/object/isEqualNever.d.ts.map +0 -11
- package/types/object/mapObject.d.ts +0 -6
- package/types/object/mapObject.d.ts.map +0 -11
- package/types/object/object.d.ts +0 -12
- package/types/object/object.d.ts.map +0 -11
- package/types/object/objectUniqueKey.d.ts +0 -3
- package/types/object/objectUniqueKey.d.ts.map +0 -11
- package/types/react/createGlobalContext.d.ts +0 -4
- package/types/react/createGlobalContext.d.ts.map +0 -11
- package/types/react/getCurrentComponentStack.d.ts +0 -3
- package/types/react/getCurrentComponentStack.d.ts.map +0 -11
- package/types/server/ensureEnv.d.ts +0 -3
- package/types/server/ensureEnv.d.ts.map +0 -11
- package/types/server/getHeaders.d.ts +0 -3
- package/types/server/getHeaders.d.ts.map +0 -11
- package/types/server/prettyPrintRequest.d.ts +0 -3
- package/types/server/prettyPrintRequest.d.ts.map +0 -11
- package/types/server/prettyPrintResponse.d.ts +0 -3
- package/types/server/prettyPrintResponse.d.ts.map +0 -11
- package/types/server/streamToString.d.ts +0 -3
- package/types/server/streamToString.d.ts.map +0 -11
- package/types/server-only.d.ts +0 -2
- package/types/server-only.d.ts.map +0 -11
- package/types/storage/createStorage.d.ts +0 -65
- package/types/storage/createStorage.d.ts.map +0 -11
- package/types/storage/driver.d.ts +0 -5
- package/types/storage/driver.d.ts.map +0 -11
- package/types/storage/storage.test.d.ts +0 -3
- package/types/storage/storage.test.d.ts.map +0 -11
- package/types/storage/types.d.ts +0 -8
- package/types/storage/types.d.ts.map +0 -11
- package/types/string/dedent.d.ts +0 -3
- package/types/string/dedent.d.ts.map +0 -11
- package/types/string/ellipsis.d.ts +0 -3
- package/types/string/ellipsis.d.ts.map +0 -11
- package/types/string/hash.d.ts +0 -4
- package/types/string/hash.d.ts.map +0 -11
- package/types/string/insertAtIndex.d.ts +0 -3
- package/types/string/insertAtIndex.d.ts.map +0 -11
- package/types/string/nbspLastWord.d.ts +0 -7
- package/types/string/nbspLastWord.d.ts.map +0 -11
- package/types/string/pickLast.d.ts +0 -3
- package/types/string/pickLast.d.ts.map +0 -11
- package/types/string/pluralize.d.ts +0 -5
- package/types/string/pluralize.d.ts.map +0 -11
- package/types/string/pluralize.native.d.ts +0 -4
- package/types/string/pluralize.native.d.ts.map +0 -13
- package/types/string/randomId.d.ts +0 -3
- package/types/string/randomId.d.ts.map +0 -11
- package/types/string/slugify.d.ts +0 -3
- package/types/string/slugify.d.ts.map +0 -11
- package/types/string/truncateList.d.ts +0 -17
- package/types/string/truncateList.d.ts.map +0 -11
- package/types/time/formatDate.d.ts +0 -5
- package/types/time/formatDate.d.ts.map +0 -11
- package/types/time/formatDateRelative.d.ts +0 -3
- package/types/time/formatDateRelative.d.ts.map +0 -11
- package/types/time/formatDistanceToNow.d.ts +0 -3
- package/types/time/formatDistanceToNow.d.ts.map +0 -11
- package/types/time/time.d.ts +0 -29
- package/types/time/time.d.ts.map +0 -13
- package/types/time/useTimer.d.ts +0 -11
- package/types/time/useTimer.d.ts.map +0 -11
- package/types/types/NullToOptional.d.ts +0 -3
- package/types/types/NullToOptional.d.ts.map +0 -11
- package/types/types/object.d.ts +0 -16
- package/types/types/object.d.ts.map +0 -11
- package/types/types/react.d.ts +0 -3
- package/types/types/react.d.ts.map +0 -11
- package/types/types/timer.d.ts +0 -3
- package/types/types/timer.d.ts.map +0 -11
- package/types/types/tuple.d.ts +0 -3
- package/types/types/tuple.d.ts.map +0 -11
- package/types/url/urlSanitize.d.ts +0 -3
- package/types/url/urlSanitize.d.ts.map +0 -11
- package/types/url/urlValidate.d.ts +0 -3
- package/types/url/urlValidate.d.ts.map +0 -11
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,cAAc,eAA8B;AAO5C,OAAO,iBAAS,oBAAoB,GAAG,aAAa,cAAc,IAAI,QAAQ",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/react/createGlobalContext.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import { type Context, createContext } from 'react'\n\nimport { globalValue } from '../global/globalValue'\n\n// create or retrieve a React context that is stored on `globalThis`.\n// this ensures a stable singleton that survives hot-reloads during development.\n\nexport function createGlobalContext<T>(key: string, defaultValue: T): Context<T> {\n return globalValue(key, () => createContext<T>(defaultValue))\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAEA,OAAO,cAAM,2BAA4B,SAAS",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/react/getCurrentComponentStack.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import React from 'react'\n\nexport const getCurrentComponentStack = (format?: 'short'): string => {\n if (process.env.NODE_ENV === 'development') {\n const stack =\n React[\n '__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE'\n ].getCurrentStack()\n\n if (format === 'short') {\n return formatStackToShort(stack)\n }\n\n return stack\n }\n\n return `(prod, no stack)`\n}\n\nconst formatStackToShort = (stack: string): string => {\n if (process.env.NODE_ENV === 'development') {\n const lines = stack\n // huge stack was causing issues\n .slice(0, 6000)\n .split('\\n')\n\n const componentNames: string[] = []\n\n for (const line of lines) {\n // Extract component names from patterns like \"at ComponentName (\"\n // Also handle cases like \"at Route((chat))\" or \"Route() (\"\n const match = line.match(/\\s*at\\s+([A-Z][a-zA-Z0-9_]*)\\s*\\(/)\n if (match) {\n const componentName = match[1]\n // Filter out framework internals and keep user components\n if (\n componentName &&\n componentName !== 'Array' &&\n componentName !== 'Root' &&\n componentName !== 'Route'\n ) {\n componentNames.push(componentName)\n if (componentNames.length > 10) {\n // avoid too many\n break\n }\n }\n }\n }\n\n return componentNames.join(' < ')\n }\n\n return stack\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAEA,OAAO,iBAAS,UAAU,cAAc",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/server/ensureEnv.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"// note doesnt work on client because Vite injects process.env\n\nexport function ensureEnv(name: string, defaultValue?: string): string {\n if (typeof process.env[name] === 'string') {\n return process.env[name] || defaultValue || ''\n }\n if (defaultValue !== undefined) {\n return defaultValue\n }\n if (process.env.ALLOW_MISSING_ENV) {\n return ''\n }\n if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {\n if (typeof defaultValue === 'undefined') {\n console.warn(` - missing env ${name}`)\n }\n return ''\n }\n throw new Error(`Environment variable ${name} not set.`)\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAS,WAAW,SAAS,UAAU",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/server/getHeaders.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export function getHeaders(headers: Headers): Record<string, unknown> {\n const headersOut: Record<string, unknown> = {}\n headers.forEach((value, key) => {\n headersOut[key] = value\n })\n return headersOut\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAGA,OAAO,iBAAe,mBAAmB,SAAS,UAAU",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/server/prettyPrintRequest.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"// import { getHeaders } from './getHeaders'\n// import { streamToString } from './streamToString'\n\nexport async function prettyPrintRequest(request: Request): Promise<void> {\n // one bug potentially, clone casues: Unhandled rejection at [object Promise] TypeError: unusable\n // const request = requestIn.clone()\n\n // const requestDetails = {\n // method: request.method,\n // url: request.url,\n // headers: getHeaders(requestIn.headers),\n // body: request.body ? await streamToString(request.body) : null,\n // }\n\n console.info(request)\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAGA,OAAO,iBAAe,oBAAoB,YAAY,WAAW",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/server/prettyPrintResponse.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import { getHeaders } from './getHeaders'\nimport { streamToString } from './streamToString'\n\nexport async function prettyPrintResponse(responseIn: Response): Promise<void> {\n const response = responseIn.clone()\n\n const responseDetails = {\n status: response.status,\n statusText: response.statusText,\n headers: getHeaders(responseIn.headers),\n body: response.body ? await streamToString(response.body) : null,\n }\n\n console.info(responseDetails)\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAe,eAAe,QAAQ,iBAAiB",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/server/streamToString.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export async function streamToString(stream: ReadableStream): Promise<string> {\n const reader = stream.getReader()\n const decoder = new TextDecoder()\n let result = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n result += decoder.decode(value, { stream: true })\n }\n } catch (error) {\n console.error('Error reading the stream:', error)\n } finally {\n reader.releaseLock()\n }\n\n return result\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
package/types/server-only.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* namespaced storage interface with JSON serialization
|
|
3
|
-
* @template K - key type (string literal union for type-safe keys)
|
|
4
|
-
* @template V - value type (automatically JSON serialized/deserialized)
|
|
5
|
-
*/
|
|
6
|
-
export interface Storage<
|
|
7
|
-
K extends string = string,
|
|
8
|
-
V = unknown
|
|
9
|
-
> {
|
|
10
|
-
/** get a JSON-parsed value by key */
|
|
11
|
-
get(key: K): V | undefined;
|
|
12
|
-
/** set a value (JSON serialized) */
|
|
13
|
-
set(key: K, value: V): void;
|
|
14
|
-
/** remove a key */
|
|
15
|
-
remove(key: K): void;
|
|
16
|
-
/** check if key exists */
|
|
17
|
-
has(key: K): boolean;
|
|
18
|
-
/** get all keys in this namespace */
|
|
19
|
-
keys(): K[];
|
|
20
|
-
/** remove all keys in this namespace */
|
|
21
|
-
clear(): void;
|
|
22
|
-
/** get raw string value (no JSON parsing) - localStorage compatible */
|
|
23
|
-
getItem(key: K): string | null;
|
|
24
|
-
/** set raw string value (no JSON serialization) - localStorage compatible */
|
|
25
|
-
setItem(key: K, value: string): void;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* create a namespaced storage instance
|
|
29
|
-
* @param namespace - unique prefix for all keys (throws if already used)
|
|
30
|
-
* @returns storage instance with get/set (JSON) and getItem/setItem (raw) methods
|
|
31
|
-
* @example
|
|
32
|
-
* const store = createStorage<'token' | 'user', string>('auth')
|
|
33
|
-
* store.set('token', 'abc123')
|
|
34
|
-
* store.get('token') // 'abc123'
|
|
35
|
-
*/
|
|
36
|
-
export declare function createStorage<
|
|
37
|
-
K extends string,
|
|
38
|
-
V
|
|
39
|
-
>(namespace: string): Storage<K, V>;
|
|
40
|
-
/**
|
|
41
|
-
* single-value storage interface
|
|
42
|
-
* @template T - value type (automatically JSON serialized/deserialized)
|
|
43
|
-
*/
|
|
44
|
-
export interface StorageValue<T> {
|
|
45
|
-
/** get the stored value */
|
|
46
|
-
get(): T | undefined;
|
|
47
|
-
/** set the value */
|
|
48
|
-
set(value: T): void;
|
|
49
|
-
/** remove the value */
|
|
50
|
-
remove(): void;
|
|
51
|
-
/** check if value exists */
|
|
52
|
-
has(): boolean;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* create a single-value storage (wrapper around createStorage)
|
|
56
|
-
* @param key - unique storage key
|
|
57
|
-
* @returns storage value instance
|
|
58
|
-
* @example
|
|
59
|
-
* const token = createStorageValue<string>('auth-token')
|
|
60
|
-
* token.set('abc123')
|
|
61
|
-
* token.get() // 'abc123'
|
|
62
|
-
*/
|
|
63
|
-
export declare function createStorageValue<T>(key: string): StorageValue<T>;
|
|
64
|
-
|
|
65
|
-
//# sourceMappingURL=createStorage.d.ts.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": ";;;;;AASA,iBAAiB;CAAQ;CAA2B;EAAa;;CAE/D,IAAI,KAAK,IAAI;;CAEb,IAAI,KAAK,GAAG,OAAO;;CAEnB,OAAO,KAAK;;CAEZ,IAAI,KAAK;;CAET,QAAQ;;CAER;;CAEA,QAAQ,KAAK;;CAEb,QAAQ,KAAK,GAAG;;;;;;;;;;;AAYlB,OAAO,iBAAS;CAAc;CAAkB;EAAG,oBAAoB,QAAQ,GAAG;;;;;AA2ElF,iBAAiB,aAAa,GAAG;;CAE/B,OAAO;;CAEP,IAAI,OAAO;;CAEX;;CAEA;;;;;;;;;;;AAYF,OAAO,iBAAS,mBAAmB,GAAG,cAAc,aAAa",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/storage/createStorage.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import { getStorageDriver } from './driver'\n\nconst namespaces = new Set<string>()\n\n/**\n * namespaced storage interface with JSON serialization\n * @template K - key type (string literal union for type-safe keys)\n * @template V - value type (automatically JSON serialized/deserialized)\n */\nexport interface Storage<K extends string = string, V = unknown> {\n /** get a JSON-parsed value by key */\n get(key: K): V | undefined\n /** set a value (JSON serialized) */\n set(key: K, value: V): void\n /** remove a key */\n remove(key: K): void\n /** check if key exists */\n has(key: K): boolean\n /** get all keys in this namespace */\n keys(): K[]\n /** remove all keys in this namespace */\n clear(): void\n /** get raw string value (no JSON parsing) - localStorage compatible */\n getItem(key: K): string | null\n /** set raw string value (no JSON serialization) - localStorage compatible */\n setItem(key: K, value: string): void\n}\n\n/**\n * create a namespaced storage instance\n * @param namespace - unique prefix for all keys (throws if already used)\n * @returns storage instance with get/set (JSON) and getItem/setItem (raw) methods\n * @example\n * const store = createStorage<'token' | 'user', string>('auth')\n * store.set('token', 'abc123')\n * store.get('token') // 'abc123'\n */\nexport function createStorage<K extends string, V>(namespace: string): Storage<K, V> {\n if (namespaces.has(namespace)) {\n throw new Error(`storage namespace already exists: ${namespace}`)\n }\n namespaces.add(namespace)\n\n const prefix = `${namespace}:`\n const prefixKey = (key: string) => `${prefix}${key}`\n\n return {\n get(key: K): V | undefined {\n const driver = getStorageDriver()\n if (!driver) return undefined\n const raw = driver.getItem(prefixKey(key))\n if (raw == null) return undefined\n try {\n return JSON.parse(raw)\n } catch {\n return undefined\n }\n },\n\n set(key: K, value: V): void {\n const driver = getStorageDriver()\n if (!driver) return\n driver.setItem(prefixKey(key), JSON.stringify(value))\n },\n\n remove(key: K): void {\n const driver = getStorageDriver()\n if (!driver) return\n driver.removeItem(prefixKey(key))\n },\n\n has(key: K): boolean {\n const driver = getStorageDriver()\n if (!driver) return false\n return driver.getItem(prefixKey(key)) != null\n },\n\n keys(): K[] {\n const driver = getStorageDriver()\n if (!driver) return []\n return driver\n .getAllKeys()\n .filter((k) => k.startsWith(prefix))\n .map((k) => k.slice(prefix.length) as K)\n },\n\n clear(): void {\n const driver = getStorageDriver()\n if (!driver) return\n for (const key of this.keys()) {\n driver.removeItem(prefixKey(key))\n }\n },\n\n getItem(key: K): string | null {\n const driver = getStorageDriver()\n if (!driver) return null\n return driver.getItem(prefixKey(key)) ?? null\n },\n\n setItem(key: K, value: string): void {\n const driver = getStorageDriver()\n if (!driver) return\n driver.setItem(prefixKey(key), value)\n },\n }\n}\n\n/**\n * single-value storage interface\n * @template T - value type (automatically JSON serialized/deserialized)\n */\nexport interface StorageValue<T> {\n /** get the stored value */\n get(): T | undefined\n /** set the value */\n set(value: T): void\n /** remove the value */\n remove(): void\n /** check if value exists */\n has(): boolean\n}\n\n/**\n * create a single-value storage (wrapper around createStorage)\n * @param key - unique storage key\n * @returns storage value instance\n * @example\n * const token = createStorageValue<string>('auth-token')\n * token.set('abc123')\n * token.get() // 'abc123'\n */\nexport function createStorageValue<T>(key: string): StorageValue<T> {\n const storage = createStorage<'value', T>(`_v:${key}`)\n return {\n get: (): T | undefined => storage.get('value'),\n set: (value: T): void => storage.set('value', value),\n remove: (): void => storage.remove('value'),\n has: (): boolean => storage.has('value'),\n }\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,cAAc,qBAAqB;AAInC,OAAO,iBAAS,iBAAiB,GAAG;AAIpC,OAAO,iBAAS,oBAAoB",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/storage/driver.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import type { StorageDriver } from './types'\n\nlet driver: StorageDriver | null = null\n\nexport function setStorageDriver(d: StorageDriver): void {\n driver = d\n}\n\nexport function getStorageDriver(): StorageDriver | null {\n if (driver) return driver\n if (typeof localStorage !== 'undefined' && typeof localStorage.getItem === 'function') {\n return {\n getItem: (key) => localStorage.getItem(key),\n setItem: (key, value) => localStorage.setItem(key, value),\n removeItem: (key) => localStorage.removeItem(key),\n getAllKeys: () => Object.keys(localStorage),\n }\n }\n return null\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/storage/storage.test.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"import { beforeEach, describe, expect, it } from 'vitest'\n\nimport { createStorage } from './createStorage'\nimport { getStorageDriver, setStorageDriver } from './driver'\n\n// test the storage driver system to ensure it works correctly\n// this regression test validates that the storage system initializes properly\n// which is critical for native auth to work\n\ndescribe('storage driver system', () => {\n describe('driver initialization', () => {\n it('getStorageDriver should return localStorage fallback on web', () => {\n // web environment has localStorage which should be used as fallback\n const driver = getStorageDriver()\n // in node/vitest environment, localStorage might not exist\n // but if it does, the driver should work\n if (typeof localStorage !== 'undefined') {\n expect(driver).toBeTruthy()\n }\n })\n\n it('should use custom driver when set', () => {\n const mockStorage = new Map<string, string>()\n const mockDriver = {\n getItem: (key: string) => mockStorage.get(key) ?? null,\n setItem: (key: string, value: string) => mockStorage.set(key, value),\n removeItem: (key: string) => mockStorage.delete(key),\n getAllKeys: () => Array.from(mockStorage.keys()),\n }\n\n setStorageDriver(mockDriver)\n const driver = getStorageDriver()\n expect(driver).toBe(mockDriver)\n })\n })\n\n describe('createStorage with driver', () => {\n let mockStorage: Map<string, string>\n\n beforeEach(() => {\n mockStorage = new Map<string, string>()\n const mockDriver = {\n getItem: (key: string) => mockStorage.get(key) ?? null,\n setItem: (key: string, value: string) => mockStorage.set(key, value),\n removeItem: (key: string) => mockStorage.delete(key),\n getAllKeys: () => Array.from(mockStorage.keys()),\n }\n setStorageDriver(mockDriver)\n })\n\n it('should store and retrieve values', () => {\n const storage = createStorage<'token', string>(`test-${Date.now()}-1`)\n storage.set('token', 'test-value')\n expect(storage.get('token')).toBe('test-value')\n })\n\n it('should use namespace prefix', () => {\n const namespace = `test-${Date.now()}-2`\n const storage = createStorage<'key', string>(namespace)\n storage.set('key', 'value')\n\n // verify the key in the underlying storage has the namespace prefix\n expect(mockStorage.has(`${namespace}:key`)).toBe(true)\n })\n\n it('should handle JSON serialization', () => {\n const storage = createStorage<'obj', { name: string; count: number }>(\n `test-${Date.now()}-3`\n )\n const obj = { name: 'test', count: 42 }\n storage.set('obj', obj)\n expect(storage.get('obj')).toEqual(obj)\n })\n\n it('should support raw string operations', () => {\n const storage = createStorage<'raw', string>(`test-${Date.now()}-4`)\n storage.setItem('raw', 'raw-value')\n expect(storage.getItem('raw')).toBe('raw-value')\n })\n\n it('should return undefined for missing keys', () => {\n const storage = createStorage<'missing', string>(`test-${Date.now()}-5`)\n expect(storage.get('missing')).toBeUndefined()\n })\n\n it('should support has() check', () => {\n const storage = createStorage<'exists', string>(`test-${Date.now()}-6`)\n expect(storage.has('exists')).toBe(false)\n storage.set('exists', 'value')\n expect(storage.has('exists')).toBe(true)\n })\n\n it('should support remove()', () => {\n const storage = createStorage<'removable', string>(`test-${Date.now()}-7`)\n storage.set('removable', 'value')\n expect(storage.has('removable')).toBe(true)\n storage.remove('removable')\n expect(storage.has('removable')).toBe(false)\n })\n\n it('should list keys in namespace', () => {\n const storage = createStorage<'a' | 'b' | 'c', string>(`test-${Date.now()}-8`)\n storage.set('a', '1')\n storage.set('b', '2')\n storage.set('c', '3')\n expect(storage.keys().sort()).toEqual(['a', 'b', 'c'])\n })\n\n it('should clear only namespace keys', () => {\n const ns1 = `test-${Date.now()}-9a`\n const ns2 = `test-${Date.now()}-9b`\n const storage1 = createStorage<'key', string>(ns1)\n const storage2 = createStorage<'key', string>(ns2)\n\n storage1.set('key', 'value1')\n storage2.set('key', 'value2')\n\n storage1.clear()\n\n expect(storage1.has('key')).toBe(false)\n expect(storage2.has('key')).toBe(true)\n })\n })\n\n describe('createStorage without driver (simulates native without setup)', () => {\n // this test simulates what happens on native when setupStorage.native.ts\n // is not imported before auth initialization\n\n it('should handle gracefully when operations fail', () => {\n // when driver returns null, operations should not throw\n // they should just silently fail (return undefined, do nothing)\n // this is the current behavior but we want to document it\n const storage = createStorage<'key', string>(`test-no-driver-${Date.now()}`)\n\n // these should not throw even without a driver\n expect(() => storage.get('key')).not.toThrow()\n expect(() => storage.set('key', 'value')).not.toThrow()\n expect(() => storage.remove('key')).not.toThrow()\n expect(() => storage.has('key')).not.toThrow()\n expect(() => storage.keys()).not.toThrow()\n expect(() => storage.clear()).not.toThrow()\n expect(() => storage.getItem('key')).not.toThrow()\n expect(() => storage.setItem('key', 'value')).not.toThrow()\n })\n })\n})\n\ndescribe('auth storage requirements', () => {\n // these tests document the requirements for auth storage to work correctly\n\n it('storage must be initialized before auth client creates storage instances', () => {\n // the expo auth client creates storage at module load time:\n // const expoStorage = createStorage('expo-auth-client')\n //\n // if setStorageDriver is not called before this, storage operations will fail\n // this is why setupClient.ts must run before any auth code\n\n // we verify this requirement is documented and understood\n expect(true).toBe(true)\n })\n\n it('native platforms require explicit storage driver setup', () => {\n // unlike web which has localStorage fallback, native platforms need\n // MMKV or AsyncStorage to be configured via setStorageDriver()\n //\n // this happens in setupStorage.native.ts which must be imported\n // before platformClient.native.ts creates its storage instance\n\n // we verify this requirement is documented and understood\n expect(true).toBe(true)\n })\n})\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
package/types/storage/types.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,iBAAiB,cAAc;CAC7B,QAAQ;CACR,QAAQ,aAAa;CACrB,WAAW;CACX",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/storage/types.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export interface StorageDriver {\n getItem(key: string): string | null | undefined\n setItem(key: string, value: string): void\n removeItem(key: string): void\n getAllKeys(): string[]\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
package/types/string/dedent.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAS,OAAO,SAAS,+BAA+B,GAAG",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/dedent.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export function dedent(strings: TemplateStringsArray | string, ...values: any[]): string {\n // If called as a normal function with a string\n if (typeof strings === 'string') {\n return dedentString(strings)\n }\n\n // If called as a template tag\n const result = strings.reduce((acc, str, i) => {\n return acc + str + (values[i] !== undefined ? values[i] : '')\n }, '')\n\n return dedentString(result)\n}\n\nfunction dedentString(text: string): string {\n let lines = text.replace(/^\\n/, '').split('\\n')\n\n // Find common indentation from non-empty lines\n const indentLengths = lines\n .filter((line) => line.trim().length > 0)\n .map((line) => line.match(/^[ \\t]*/)?.[0].length ?? 0)\n\n const minIndent = indentLengths.length > 0 ? Math.min(...indentLengths) : 0\n\n if (minIndent > 0) {\n lines = lines.map((line) => line.slice(minIndent))\n }\n\n return lines.join('\\n').trimEnd()\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,cAAM,WAAY,aAAa",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/ellipsis.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export const ellipsis = (str: string, maxLength: number): string => {\n // avoid running replace on huge string if its long\n const shortened = str.length > 500 ? str.slice(0, 500) : str\n const cleaned = shortened.replace(/\\s+/g, ' ').trim()\n if (cleaned.length > maxLength) {\n return cleaned.substring(0, maxLength - 3) + '…'\n }\n return cleaned\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
package/types/string/hash.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAEA,OAAO,iBAAS,WAAW;AAQ3B,OAAO,iBAAS,aAAa",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/hash.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"// simple reversible encoding - alphanumeric only\n\nexport function hashString(str: string): string {\n // convert to hex (0-9a-f)\n return str\n .split('')\n .map((c) => c.charCodeAt(0).toString(16).padStart(2, '0'))\n .join('')\n}\n\nexport function unhashString(encoded: string): string {\n // convert from hex back to string\n return (\n encoded\n .match(/.{2}/g)\n ?.map((h) => String.fromCharCode(parseInt(h, 16)))\n .join('') || ''\n )\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAS,cAAc,kBAAkB,eAAe",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/insertAtIndex.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export function insertAtIndex(original: string, index: number, toInsert: string): string {\n if (index < 0 || index > original.length) {\n throw new Error('Index out of bounds')\n }\n\n return original.slice(0, index) + toInsert + original.slice(index)\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": ";;;;AAIA,OAAO,cAAM,eAAgB",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/nbspLastWord.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"/**\n * replaces the last space in a string with a non-breaking space\n * to prevent orphaned words at the end of text blocks\n */\nexport const nbspLastWord = (text: string): string => {\n if (!text) return text\n const words = text.split(' ')\n if (words.length <= 1) return text\n return words.slice(0, -1).join(' ') + '\\u00A0' + words[words.length - 1]\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAS,SAAS,qCACvB,GAAG,GACH,GAAG,IACF,4BAA4B",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/pickLast.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export function pickLast<T extends string | null | undefined>(\n a: T,\n b: T\n): T extends string ? string : T {\n if (a == null && b == null) return undefined as any\n if (a == null) return b as any\n if (b == null) return a as any\n return (b.localeCompare(a) > 0 ? b : a) as any\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAEA,OAAO,iBAAS,UAAU,eAAe,kBAAkB;AAc3D,OAAO,iBAAS,mBAAmB,QAAQ,KAAK;AAIhD,YAAY,qBAAqB",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/pluralize.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"let pluralRules = new Intl.PluralRules('en-US')\n\nexport function pluralize(count: number, singular: string, plural: string): string {\n const grammaticalNumber = pluralRules.select(count)\n switch (grammaticalNumber) {\n case 'one':\n return `${count} ${singular}`\n case 'other':\n return `${count} ${plural}`\n default:\n throw new Error(\n `Can't pluralize: ${grammaticalNumber} for ${count} / ${singular} / ${plural}`\n )\n }\n}\n\nexport function setPluralizeLocale(locale: Intl.LocalesArgument): void {\n pluralRules = new Intl.PluralRules(locale)\n}\n\nexport type PluralizeFn = typeof pluralize\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,cAAc,mBAAmB;AAEjC,OAAO,cAAMA,WAAW",
|
|
3
|
-
"names": [
|
|
4
|
-
"pluralize: PluralizeFn"
|
|
5
|
-
],
|
|
6
|
-
"sources": [
|
|
7
|
-
"src/string/pluralize.native.ts"
|
|
8
|
-
],
|
|
9
|
-
"sourcesContent": [
|
|
10
|
-
"import type { PluralizeFn } from './pluralize'\n\nexport const pluralize: PluralizeFn = (count, singular, plural) => {\n console.info('pluralize.native.ts: TODO', count, singular, plural)\n return plural\n}\n"
|
|
11
|
-
],
|
|
12
|
-
"version": 3
|
|
13
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,cAAM,UAAW",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/slugify.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export const slugify = (input: string): string =>\n input\n .toLowerCase()\n .replace(/[\\s_]+/g, '-') // convert spaces and underscores to dashes\n .replace(/[^a-z0-9-]/g, '') // remove all non-alphanumeric except dashes\n .replace(/-+/g, '-') // replace multiple dashes with single dash\n .replace(/^-|-$/g, '') // remove leading/trailing dashes\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Truncates a list of strings to show only the first N items,
|
|
3
|
-
* with a "+X" indicator for any remaining items.
|
|
4
|
-
*
|
|
5
|
-
* @param items - Array of strings to truncate
|
|
6
|
-
* @param maxItems - Maximum number of items to show before truncating
|
|
7
|
-
* @param separator - String to use between items (default: ', ')
|
|
8
|
-
* @returns Formatted string with truncation indicator if needed
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* truncateList(['jon', 'sal', 'bob', 'ted'], 3) // "jon, sal, bob +1"
|
|
12
|
-
* truncateList(['alice', 'bob'], 3) // "alice, bob"
|
|
13
|
-
* truncateList(['a', 'b', 'c', 'd', 'e'], 2) // "a, b +3"
|
|
14
|
-
*/
|
|
15
|
-
export declare const truncateList: (items: string[], maxItems: number, separator?: string) => string;
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=truncateList.d.ts.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": ";;;;;;;;;;;;;;AAcA,OAAO,cAAM,eACX,iBACA,kBACA",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/string/truncateList.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"/**\n * Truncates a list of strings to show only the first N items,\n * with a \"+X\" indicator for any remaining items.\n *\n * @param items - Array of strings to truncate\n * @param maxItems - Maximum number of items to show before truncating\n * @param separator - String to use between items (default: ', ')\n * @returns Formatted string with truncation indicator if needed\n *\n * @example\n * truncateList(['jon', 'sal', 'bob', 'ted'], 3) // \"jon, sal, bob +1\"\n * truncateList(['alice', 'bob'], 3) // \"alice, bob\"\n * truncateList(['a', 'b', 'c', 'd', 'e'], 2) // \"a, b +3\"\n */\nexport const truncateList = (\n items: string[],\n maxItems: number,\n separator: string = ', '\n): string => {\n if (items.length <= maxItems) {\n return items.join(separator)\n }\n\n const visibleItems = items.slice(0, maxItems)\n const remainingCount = items.length - maxItems\n\n return `${visibleItems.join(separator)} +${remainingCount}`\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAEA,OAAO,iBAAS,WACd,MAAM,MACN,UAAU;CAAE",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/time/formatDate.tsx"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"const currentYear = new Date().getFullYear()\n\nexport function formatDate(\n date: Date,\n options?: { daySuffix?: boolean }\n): [string, string] | [string, string, string] {\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ]\n\n const day = date.getDate()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n\n const dayString = options?.daySuffix ? getOrdinalSuffix(day) : `${day}`\n\n if (year === currentYear) {\n return [`${month}`, dayString]\n }\n\n return [`${month}`, dayString, `${year}`]\n}\n\nconst getOrdinalSuffix = (n: number) => {\n if (n >= 11 && n <= 13) return 'th'\n switch (n % 10) {\n case 1:\n return 'st'\n case 2:\n return 'nd'\n case 3:\n return 'rd'\n default:\n return 'th'\n }\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAWA,OAAO,iBAAS,mBAAmB,MAAM",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/time/formatDateRelative.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"/**\n * Formats a date relative to the current time:\n * - If within the last month: just show time (e.g., \"5:50pm\")\n * - If this year but older than a month: show \"Jun 2, 5:50pm\"\n * - If before this year: show \"Jun 2, 2025, 5:50pm\"\n */\n\nfunction lowerCaseTime(formatted: string): string {\n return formatted.replace(/\\s?(AM|PM)/g, (_, ampm) => ampm.toLowerCase())\n}\n\nexport function formatDateRelative(date: Date | string | number): string {\n const messageDate = new Date(date)\n const now = new Date()\n\n // if it's today\n const isToday =\n messageDate.getFullYear() === now.getFullYear() &&\n messageDate.getMonth() === now.getMonth() &&\n messageDate.getDate() === now.getDate()\n\n // check if it's within the last month\n const oneMonthAgo = new Date(now)\n oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1)\n const isWithinLastMonth = messageDate >= oneMonthAgo\n\n // if it's this year\n const isThisYear = messageDate.getFullYear() === now.getFullYear()\n\n if (isToday) {\n // just time for today\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n if (isWithinLastMonth) {\n // just time for dates within the last month\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n if (isThisYear) {\n // Show \"Jun 2, 5:50pm\" for this year\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n // Show \"Jun 2, 2025, 5:50pm\" for previous years\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mappings": "AAAA,OAAO,iBAAS,oBAAoB",
|
|
3
|
-
"names": [],
|
|
4
|
-
"sources": [
|
|
5
|
-
"src/time/formatDistanceToNow.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"export function formatDistanceToNow(timestamp: number): string {\n const now = Date.now()\n const diff = now - timestamp\n\n const minutes = Math.floor(diff / 60000)\n const hours = Math.floor(diff / 3600000)\n const days = Math.floor(diff / 86400000)\n\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m`\n if (hours < 24) return `${hours}h`\n if (days < 7) return `${days}d`\n if (days < 30) return `${Math.floor(days / 7)}w`\n if (days < 365) return `${Math.floor(days / 30)}mo`\n\n return `${Math.floor(days / 365)}y`\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"version": 3
|
|
11
|
-
}
|