qstd 0.3.76 → 0.3.78

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.
@@ -265,6 +265,7 @@ __export(time_exports, {
265
265
  formatDateRange: () => formatDateRange,
266
266
  formatDuration: () => formatDuration,
267
267
  formatThreadDateRange: () => formatThreadDateRange,
268
+ formatTimeAgo: () => formatTimeAgo,
268
269
  now: () => now,
269
270
  sleep: () => sleep,
270
271
  startTimer: () => startTimer,
@@ -389,14 +390,43 @@ var formatDate = (input, options = {}) => {
389
390
  return includeTime ? dateFns.format(date2, "MMM d, yyyy h:mm a") : dateFns.format(date2, "MMM d, yyyy");
390
391
  case "long":
391
392
  return includeTime ? dateFns.format(date2, "MMMM d, yyyy 'at' h:mm a") : dateFns.format(date2, "MMMM d, yyyy");
392
- case "relative":
393
- return dateFns.formatDistanceToNow(date2, { addSuffix: true });
394
393
  case "year":
395
394
  return dateFns.format(date2, "yyyy");
396
395
  default:
397
396
  return includeTime ? dateFns.format(date2, "MMM d, yyyy h:mm a") : dateFns.format(date2, "MMM d, yyyy");
398
397
  }
399
398
  };
399
+ var formatTimeAgo = (input, options = {}) => {
400
+ const { verbose = false } = options;
401
+ let date2;
402
+ if (typeof input === "string") {
403
+ date2 = new Date(input);
404
+ } else if (typeof input === "number") {
405
+ date2 = new Date(input);
406
+ } else {
407
+ date2 = input;
408
+ }
409
+ if (isNaN(date2.getTime())) {
410
+ return "Invalid Date";
411
+ }
412
+ if (verbose) {
413
+ return dateFns.formatDistanceToNow(date2, { addSuffix: true });
414
+ }
415
+ const diffMs = Date.now() - date2.getTime();
416
+ const diffSeconds = Math.floor(diffMs / 1e3);
417
+ const diffMinutes = Math.floor(diffSeconds / 60);
418
+ const diffHours = Math.floor(diffMinutes / 60);
419
+ const diffDays = Math.floor(diffHours / 24);
420
+ const diffWeeks = Math.floor(diffDays / 7);
421
+ const diffMonths = Math.floor(diffDays / 30);
422
+ const diffYears = Math.floor(diffDays / 365);
423
+ if (diffYears > 0) return `${diffYears}y ago`;
424
+ if (diffMonths > 0) return `${diffMonths}mo ago`;
425
+ if (diffWeeks > 0) return `${diffWeeks}w ago`;
426
+ if (diffDays > 0) return `${diffDays}d ago`;
427
+ if (diffHours > 0) return `${diffHours}h ago`;
428
+ return "just now";
429
+ };
400
430
  var toDate = (input) => typeof input === "string" || typeof input === "number" ? new Date(input) : input;
401
431
  var formatDateRange = (startInput, endInput, options = {}) => {
402
432
  const now2 = options.now ?? /* @__PURE__ */ new Date();
@@ -1,4 +1,4 @@
1
- import { format, formatDistanceToNow, formatISO, isSameYear, isSameMonth, isSameDay, addSeconds, addMinutes, addHours, addDays, addWeeks, addBusinessDays, addMonths, addYears } from 'date-fns';
1
+ import { format, formatISO, formatDistanceToNow, isSameYear, isSameMonth, isSameDay, addSeconds, addMinutes, addHours, addDays, addWeeks, addBusinessDays, addMonths, addYears } from 'date-fns';
2
2
  import React from 'react';
3
3
 
4
4
  var __defProp = Object.defineProperty;
@@ -258,6 +258,7 @@ __export(time_exports, {
258
258
  formatDateRange: () => formatDateRange,
259
259
  formatDuration: () => formatDuration,
260
260
  formatThreadDateRange: () => formatThreadDateRange,
261
+ formatTimeAgo: () => formatTimeAgo,
261
262
  now: () => now,
262
263
  sleep: () => sleep,
263
264
  startTimer: () => startTimer,
@@ -382,14 +383,43 @@ var formatDate = (input, options = {}) => {
382
383
  return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
383
384
  case "long":
384
385
  return includeTime ? format(date2, "MMMM d, yyyy 'at' h:mm a") : format(date2, "MMMM d, yyyy");
385
- case "relative":
386
- return formatDistanceToNow(date2, { addSuffix: true });
387
386
  case "year":
388
387
  return format(date2, "yyyy");
389
388
  default:
390
389
  return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
391
390
  }
392
391
  };
392
+ var formatTimeAgo = (input, options = {}) => {
393
+ const { verbose = false } = options;
394
+ let date2;
395
+ if (typeof input === "string") {
396
+ date2 = new Date(input);
397
+ } else if (typeof input === "number") {
398
+ date2 = new Date(input);
399
+ } else {
400
+ date2 = input;
401
+ }
402
+ if (isNaN(date2.getTime())) {
403
+ return "Invalid Date";
404
+ }
405
+ if (verbose) {
406
+ return formatDistanceToNow(date2, { addSuffix: true });
407
+ }
408
+ const diffMs = Date.now() - date2.getTime();
409
+ const diffSeconds = Math.floor(diffMs / 1e3);
410
+ const diffMinutes = Math.floor(diffSeconds / 60);
411
+ const diffHours = Math.floor(diffMinutes / 60);
412
+ const diffDays = Math.floor(diffHours / 24);
413
+ const diffWeeks = Math.floor(diffDays / 7);
414
+ const diffMonths = Math.floor(diffDays / 30);
415
+ const diffYears = Math.floor(diffDays / 365);
416
+ if (diffYears > 0) return `${diffYears}y ago`;
417
+ if (diffMonths > 0) return `${diffMonths}mo ago`;
418
+ if (diffWeeks > 0) return `${diffWeeks}w ago`;
419
+ if (diffDays > 0) return `${diffDays}d ago`;
420
+ if (diffHours > 0) return `${diffHours}h ago`;
421
+ return "just now";
422
+ };
393
423
  var toDate = (input) => typeof input === "string" || typeof input === "number" ? new Date(input) : input;
394
424
  var formatDateRange = (startInput, endInput, options = {}) => {
395
425
  const now2 = options.now ?? /* @__PURE__ */ new Date();
@@ -1,30 +1,47 @@
1
1
  /**
2
- * these 2 lsis should solve all future lsis. Lsi can be a
3
- * generic type that has different sk based on the pk.
4
- * E.g. pkUser can store username in lsi and pkDocument
5
- * can store id. By lsi being a generic field, can serve
6
- * the role of multiple lsis.
2
+ * Generic LSIs (1-5) for flexible querying.
3
+ *
4
+ * DynamoDB allows max 5 LSIs per table. These generic LSIs can store
5
+ * different values per partition key, enabling flexible query patterns.
6
+ *
7
+ * Since LSIs are local to each partition, the same LSI attribute can
8
+ * serve different purposes across partitions.
9
+ *
10
+ * @example
11
+ * // pk="user" partition
12
+ * lsi1: username - query users by username
13
+ * lsi2: normalized - query by normalized name for search
14
+ * lsi3: email - query users by email
15
+ *
16
+ * // pk="media" partition
17
+ * lsi1: type#<createdAt> - filter by type, sort by created
18
+ * lsi2: created#<ts> - sort by created date
19
+ * lsi3: plays#<count> - sort by play count
20
+ * lsi4: fingerprint#<h> - find by perceptual hash
21
+ * lsi5: lastPlayed#<ts> - sort by last played
22
+ *
23
+ * // pk="image" partition
24
+ * lsi1: phash#<hash> - find by perceptual hash (dHash)
25
+ * lsi2: created#<ts> - sort by created date
7
26
  */
8
- export declare const lsi: {
9
- readonly name: "lsi";
10
- readonly sk: "lsi";
27
+ export declare const lsi1: {
28
+ readonly name: "lsi1";
29
+ readonly sk: "lsi1";
11
30
  };
12
31
  export declare const lsi2: {
13
32
  readonly name: "lsi2";
14
33
  readonly sk: "lsi2";
15
34
  };
16
- export declare const lsiUsername: {
17
- readonly name: "username-lsi";
18
- readonly sk: "username";
35
+ export declare const lsi3: {
36
+ readonly name: "lsi3";
37
+ readonly sk: "lsi3";
19
38
  };
20
- export declare const lsiNormalized: {
21
- /** use in index_name */
22
- readonly name: "normalized-lsi";
23
- readonly sk: "normalized";
39
+ export declare const lsi4: {
40
+ readonly name: "lsi4";
41
+ readonly sk: "lsi4";
24
42
  };
25
- export declare const lsiPhash: {
26
- /** use in index_name */
27
- readonly name: "phash-lsi";
28
- readonly sk: "phash";
43
+ export declare const lsi5: {
44
+ readonly name: "lsi5";
45
+ readonly sk: "lsi5";
29
46
  };
30
47
  //# sourceMappingURL=literals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"literals.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/literals.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,GAAG;;;CAAsC,CAAC;AACvD,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAE1D,eAAO,MAAM,WAAW;;;CAGd,CAAC;AAGX,eAAO,MAAM,aAAa;IACxB,wBAAwB;;;CAGhB,CAAC;AAGX,eAAO,MAAM,QAAQ;IACnB,wBAAwB;;;CAGhB,CAAC"}
1
+ {"version":3,"file":"literals.d.ts","sourceRoot":"","sources":["../../../../src/server/aws/ddb/literals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAC1D,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAC1D,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAC1D,eAAO,MAAM,IAAI;;;CAAwC,CAAC;AAC1D,eAAO,MAAM,IAAI;;;CAAwC,CAAC"}
@@ -277,6 +277,7 @@ __export(time_exports, {
277
277
  formatDateRange: () => formatDateRange,
278
278
  formatDuration: () => formatDuration,
279
279
  formatThreadDateRange: () => formatThreadDateRange,
280
+ formatTimeAgo: () => formatTimeAgo,
280
281
  now: () => now,
281
282
  sleep: () => sleep,
282
283
  startTimer: () => startTimer,
@@ -401,14 +402,43 @@ var formatDate = (input, options = {}) => {
401
402
  return includeTime ? dateFns.format(date2, "MMM d, yyyy h:mm a") : dateFns.format(date2, "MMM d, yyyy");
402
403
  case "long":
403
404
  return includeTime ? dateFns.format(date2, "MMMM d, yyyy 'at' h:mm a") : dateFns.format(date2, "MMMM d, yyyy");
404
- case "relative":
405
- return dateFns.formatDistanceToNow(date2, { addSuffix: true });
406
405
  case "year":
407
406
  return dateFns.format(date2, "yyyy");
408
407
  default:
409
408
  return includeTime ? dateFns.format(date2, "MMM d, yyyy h:mm a") : dateFns.format(date2, "MMM d, yyyy");
410
409
  }
411
410
  };
411
+ var formatTimeAgo = (input, options = {}) => {
412
+ const { verbose = false } = options;
413
+ let date2;
414
+ if (typeof input === "string") {
415
+ date2 = new Date(input);
416
+ } else if (typeof input === "number") {
417
+ date2 = new Date(input);
418
+ } else {
419
+ date2 = input;
420
+ }
421
+ if (isNaN(date2.getTime())) {
422
+ return "Invalid Date";
423
+ }
424
+ if (verbose) {
425
+ return dateFns.formatDistanceToNow(date2, { addSuffix: true });
426
+ }
427
+ const diffMs = Date.now() - date2.getTime();
428
+ const diffSeconds = Math.floor(diffMs / 1e3);
429
+ const diffMinutes = Math.floor(diffSeconds / 60);
430
+ const diffHours = Math.floor(diffMinutes / 60);
431
+ const diffDays = Math.floor(diffHours / 24);
432
+ const diffWeeks = Math.floor(diffDays / 7);
433
+ const diffMonths = Math.floor(diffDays / 30);
434
+ const diffYears = Math.floor(diffDays / 365);
435
+ if (diffYears > 0) return `${diffYears}y ago`;
436
+ if (diffMonths > 0) return `${diffMonths}mo ago`;
437
+ if (diffWeeks > 0) return `${diffWeeks}w ago`;
438
+ if (diffDays > 0) return `${diffDays}d ago`;
439
+ if (diffHours > 0) return `${diffHours}h ago`;
440
+ return "just now";
441
+ };
412
442
  var toDate = (input) => typeof input === "string" || typeof input === "number" ? new Date(input) : input;
413
443
  var formatDateRange = (startInput, endInput, options = {}) => {
414
444
  const now2 = options.now ?? /* @__PURE__ */ new Date();
@@ -1193,11 +1223,11 @@ __export(ddb_exports, {
1193
1223
  create: () => create2,
1194
1224
  deleteTable: () => deleteTable,
1195
1225
  find: () => find,
1196
- lsi: () => lsi,
1226
+ lsi1: () => lsi1,
1197
1227
  lsi2: () => lsi2,
1198
- lsiNormalized: () => lsiNormalized,
1199
- lsiPhash: () => lsiPhash,
1200
- lsiUsername: () => lsiUsername,
1228
+ lsi3: () => lsi3,
1229
+ lsi4: () => lsi4,
1230
+ lsi5: () => lsi5,
1201
1231
  remove: () => remove2,
1202
1232
  save: () => save,
1203
1233
  tableExists: () => tableExists
@@ -1773,22 +1803,11 @@ var tableExists = async (ddb, props) => {
1773
1803
  };
1774
1804
 
1775
1805
  // src/server/aws/ddb/literals.ts
1776
- var lsi = { name: "lsi", sk: "lsi" };
1806
+ var lsi1 = { name: "lsi1", sk: "lsi1" };
1777
1807
  var lsi2 = { name: "lsi2", sk: "lsi2" };
1778
- var lsiUsername = {
1779
- name: "username-lsi",
1780
- sk: "username"
1781
- };
1782
- var lsiNormalized = {
1783
- /** use in index_name */
1784
- name: "normalized-lsi",
1785
- sk: "normalized"
1786
- };
1787
- var lsiPhash = {
1788
- /** use in index_name */
1789
- name: "phash-lsi",
1790
- sk: "phash"
1791
- };
1808
+ var lsi3 = { name: "lsi3", sk: "lsi3" };
1809
+ var lsi4 = { name: "lsi4", sk: "lsi4" };
1810
+ var lsi5 = { name: "lsi5", sk: "lsi5" };
1792
1811
  var validateTableName = (tableName) => {
1793
1812
  const regex = /^[a-zA-Z0-9_.-]{3,255}$/;
1794
1813
  if (!regex.test(tableName)) {
@@ -1814,10 +1833,10 @@ var clearTableSchema = (table) => {
1814
1833
  }
1815
1834
  if (table.LocalSecondaryIndexes && table.LocalSecondaryIndexes.length > 0) {
1816
1835
  cleanTable.LocalSecondaryIndexes = table.LocalSecondaryIndexes.map(
1817
- (lsi3) => ({
1818
- IndexName: lsi3.IndexName,
1819
- KeySchema: lsi3.KeySchema,
1820
- Projection: lsi3.Projection
1836
+ (lsi) => ({
1837
+ IndexName: lsi.IndexName,
1838
+ KeySchema: lsi.KeySchema,
1839
+ Projection: lsi.Projection
1821
1840
  })
1822
1841
  );
1823
1842
  }
@@ -1,4 +1,4 @@
1
- import { format, formatDistanceToNow, formatISO, isSameYear, isSameMonth, isSameDay, addSeconds, addMinutes, addHours, addDays, addWeeks, addBusinessDays, addMonths, addYears } from 'date-fns';
1
+ import { format, formatISO, formatDistanceToNow, isSameYear, isSameMonth, isSameDay, addSeconds, addMinutes, addHours, addDays, addWeeks, addBusinessDays, addMonths, addYears } from 'date-fns';
2
2
  import awaitSpawn from 'await-spawn';
3
3
  import { promises } from 'fs';
4
4
  import { ArkErrors } from 'arktype';
@@ -269,6 +269,7 @@ __export(time_exports, {
269
269
  formatDateRange: () => formatDateRange,
270
270
  formatDuration: () => formatDuration,
271
271
  formatThreadDateRange: () => formatThreadDateRange,
272
+ formatTimeAgo: () => formatTimeAgo,
272
273
  now: () => now,
273
274
  sleep: () => sleep,
274
275
  startTimer: () => startTimer,
@@ -393,14 +394,43 @@ var formatDate = (input, options = {}) => {
393
394
  return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
394
395
  case "long":
395
396
  return includeTime ? format(date2, "MMMM d, yyyy 'at' h:mm a") : format(date2, "MMMM d, yyyy");
396
- case "relative":
397
- return formatDistanceToNow(date2, { addSuffix: true });
398
397
  case "year":
399
398
  return format(date2, "yyyy");
400
399
  default:
401
400
  return includeTime ? format(date2, "MMM d, yyyy h:mm a") : format(date2, "MMM d, yyyy");
402
401
  }
403
402
  };
403
+ var formatTimeAgo = (input, options = {}) => {
404
+ const { verbose = false } = options;
405
+ let date2;
406
+ if (typeof input === "string") {
407
+ date2 = new Date(input);
408
+ } else if (typeof input === "number") {
409
+ date2 = new Date(input);
410
+ } else {
411
+ date2 = input;
412
+ }
413
+ if (isNaN(date2.getTime())) {
414
+ return "Invalid Date";
415
+ }
416
+ if (verbose) {
417
+ return formatDistanceToNow(date2, { addSuffix: true });
418
+ }
419
+ const diffMs = Date.now() - date2.getTime();
420
+ const diffSeconds = Math.floor(diffMs / 1e3);
421
+ const diffMinutes = Math.floor(diffSeconds / 60);
422
+ const diffHours = Math.floor(diffMinutes / 60);
423
+ const diffDays = Math.floor(diffHours / 24);
424
+ const diffWeeks = Math.floor(diffDays / 7);
425
+ const diffMonths = Math.floor(diffDays / 30);
426
+ const diffYears = Math.floor(diffDays / 365);
427
+ if (diffYears > 0) return `${diffYears}y ago`;
428
+ if (diffMonths > 0) return `${diffMonths}mo ago`;
429
+ if (diffWeeks > 0) return `${diffWeeks}w ago`;
430
+ if (diffDays > 0) return `${diffDays}d ago`;
431
+ if (diffHours > 0) return `${diffHours}h ago`;
432
+ return "just now";
433
+ };
404
434
  var toDate = (input) => typeof input === "string" || typeof input === "number" ? new Date(input) : input;
405
435
  var formatDateRange = (startInput, endInput, options = {}) => {
406
436
  const now2 = options.now ?? /* @__PURE__ */ new Date();
@@ -1185,11 +1215,11 @@ __export(ddb_exports, {
1185
1215
  create: () => create2,
1186
1216
  deleteTable: () => deleteTable,
1187
1217
  find: () => find,
1188
- lsi: () => lsi,
1218
+ lsi1: () => lsi1,
1189
1219
  lsi2: () => lsi2,
1190
- lsiNormalized: () => lsiNormalized,
1191
- lsiPhash: () => lsiPhash,
1192
- lsiUsername: () => lsiUsername,
1220
+ lsi3: () => lsi3,
1221
+ lsi4: () => lsi4,
1222
+ lsi5: () => lsi5,
1193
1223
  remove: () => remove2,
1194
1224
  save: () => save,
1195
1225
  tableExists: () => tableExists
@@ -1765,22 +1795,11 @@ var tableExists = async (ddb, props) => {
1765
1795
  };
1766
1796
 
1767
1797
  // src/server/aws/ddb/literals.ts
1768
- var lsi = { name: "lsi", sk: "lsi" };
1798
+ var lsi1 = { name: "lsi1", sk: "lsi1" };
1769
1799
  var lsi2 = { name: "lsi2", sk: "lsi2" };
1770
- var lsiUsername = {
1771
- name: "username-lsi",
1772
- sk: "username"
1773
- };
1774
- var lsiNormalized = {
1775
- /** use in index_name */
1776
- name: "normalized-lsi",
1777
- sk: "normalized"
1778
- };
1779
- var lsiPhash = {
1780
- /** use in index_name */
1781
- name: "phash-lsi",
1782
- sk: "phash"
1783
- };
1800
+ var lsi3 = { name: "lsi3", sk: "lsi3" };
1801
+ var lsi4 = { name: "lsi4", sk: "lsi4" };
1802
+ var lsi5 = { name: "lsi5", sk: "lsi5" };
1784
1803
  var validateTableName = (tableName) => {
1785
1804
  const regex = /^[a-zA-Z0-9_.-]{3,255}$/;
1786
1805
  if (!regex.test(tableName)) {
@@ -1806,10 +1825,10 @@ var clearTableSchema = (table) => {
1806
1825
  }
1807
1826
  if (table.LocalSecondaryIndexes && table.LocalSecondaryIndexes.length > 0) {
1808
1827
  cleanTable.LocalSecondaryIndexes = table.LocalSecondaryIndexes.map(
1809
- (lsi3) => ({
1810
- IndexName: lsi3.IndexName,
1811
- KeySchema: lsi3.KeySchema,
1812
- Projection: lsi3.Projection
1828
+ (lsi) => ({
1829
+ IndexName: lsi.IndexName,
1830
+ KeySchema: lsi.KeySchema,
1831
+ Projection: lsi.Projection
1813
1832
  })
1814
1833
  );
1815
1834
  }
@@ -98,7 +98,7 @@ type DurationOptions = {
98
98
  */
99
99
  export declare const formatDuration: (value: number | null | undefined, options?: DurationOptions) => string;
100
100
  type DateInput = Date | string | number;
101
- type DateFormatStyle = "iso" | "short" | "medium" | "long" | "relative" | "year";
101
+ type DateFormatStyle = "iso" | "short" | "medium" | "long" | "year";
102
102
  type DateOptions = {
103
103
  /** Predefined format style */
104
104
  style?: DateFormatStyle;
@@ -121,6 +121,49 @@ type DateOptions = {
121
121
  * formatDate(date, { pattern: "yyyy-MM-dd" }) // Custom format
122
122
  */
123
123
  export declare const formatDate: (input: DateInput, options?: DateOptions) => string;
124
+ type TimeAgoInput = Date | string | number;
125
+ type TimeAgoOptions = {
126
+ /** Use verbose format ("about 3 hours ago") instead of compact ("3h ago"). Default: false */
127
+ verbose?: boolean;
128
+ };
129
+ /**
130
+ * Formats a past date as relative elapsed time ("3h ago", "1d ago", "just now").
131
+ *
132
+ * Compact by default for UI badges, sync indicators, and timestamps.
133
+ * Use `verbose: true` for accessibility or screen readers.
134
+ *
135
+ * @param input - Date to format (Date object, ISO string, or Unix timestamp)
136
+ * @param options - Configuration options
137
+ * @param options.verbose - Use verbose format ("about 3 hours ago") instead of compact ("3h ago")
138
+ *
139
+ * @example
140
+ * ```ts
141
+ * // COMPACT FORMAT (default) - Best for UI badges, sync indicators
142
+ *
143
+ * formatTimeAgo(new Date()) // "just now"
144
+ * formatTimeAgo(Date.now() - 1000 * 60 * 30) // "just now" (< 1 hour)
145
+ * formatTimeAgo(Date.now() - 1000 * 60 * 60 * 3) // "3h ago"
146
+ * formatTimeAgo(Date.now() - 1000 * 60 * 60 * 24) // "1d ago"
147
+ * formatTimeAgo(Date.now() - 1000 * 60 * 60 * 24 * 5) // "5d ago"
148
+ *
149
+ * // VERBOSE FORMAT - Best for accessibility, screen readers
150
+ *
151
+ * formatTimeAgo(date, { verbose: true }) // "about 3 hours ago"
152
+ * formatTimeAgo(date, { verbose: true }) // "5 days ago"
153
+ *
154
+ * // COMMON USE CASES
155
+ *
156
+ * // Search index freshness indicator
157
+ * `${count} songs indexed · ${formatTimeAgo(buildTime)}` // "1,234 songs indexed · 3h ago"
158
+ *
159
+ * // Last sync timestamp
160
+ * `Last synced ${formatTimeAgo(lastSync)}` // "Last synced 5d ago"
161
+ *
162
+ * // Comment timestamps
163
+ * `Posted ${formatTimeAgo(createdAt)}` // "Posted just now"
164
+ * ```
165
+ */
166
+ export declare const formatTimeAgo: (input: TimeAgoInput, options?: TimeAgoOptions) => string;
124
167
  type DateRangeInput = Date | string | number;
125
168
  type DateRangeOptions = {
126
169
  /** Reference date for today checks (defaults to new Date()) */
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/shared/time.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/shared/time.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qstd",
3
- "version": "0.3.76",
3
+ "version": "0.3.78",
4
4
  "description": "Standard Block component and utilities library with Panda CSS",
5
5
  "author": "malin1",
6
6
  "license": "MIT",