@ienlab/react-library 0.4.0 → 0.4.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.
@@ -1,2 +1,2 @@
1
- export {};
1
+ export * from './image';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -1,50 +1,98 @@
1
- import { collection as e, documentId as t, getDoc as n, getDocs as r, onSnapshot as i, query as a, serverTimestamp as o, where as s } from "firebase/firestore";
1
+ import { useEffect, useState } from "react";
2
+ import { AnimatePresence, motion } from "motion/react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { collection, documentId, getDoc, getDocs, onSnapshot, query, serverTimestamp, where } from "firebase/firestore";
5
+ //#region src/components/image.tsx
6
+ function CrossfadeImage({ placeholder, src, onLoadError, ...imgProps }) {
7
+ const [isLoaded, setIsLoaded] = useState(() => {
8
+ if (typeof window === "undefined" || !src) return false;
9
+ const img = new Image();
10
+ img.src = src;
11
+ return img.complete && img.naturalWidth > 0;
12
+ });
13
+ const [prevSrc, setPrevSrc] = useState(src);
14
+ if (prevSrc !== src) {
15
+ setPrevSrc(src);
16
+ setIsLoaded(false);
17
+ }
18
+ useEffect(() => {
19
+ if (!src) return;
20
+ const img = new Image();
21
+ img.src = src;
22
+ img.onload = () => setIsLoaded(true);
23
+ img.onerror = (e) => {
24
+ if (onLoadError) onLoadError(e);
25
+ else console.error("CrossfadeImage: Failed to load image", src);
26
+ };
27
+ if (img.complete && img.naturalWidth > 0) img.onload(new Event("load"));
28
+ return () => {
29
+ img.onload = null;
30
+ img.onerror = null;
31
+ };
32
+ }, [src, onLoadError]);
33
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: isLoaded && src ? /* @__PURE__ */ jsx(motion.img, {
34
+ src,
35
+ ...imgProps,
36
+ initial: { opacity: 0 },
37
+ animate: { opacity: 1 },
38
+ exit: { opacity: 0 },
39
+ style: { ...imgProps.style }
40
+ }, "loaded-image") : /* @__PURE__ */ jsx(motion.div, {
41
+ initial: { opacity: 1 },
42
+ transition: { duration: .3 },
43
+ style: { ...imgProps.style },
44
+ children: placeholder ?? /* @__PURE__ */ jsx("div", { className: "w-full h-full bg-sidebar" })
45
+ }, "placeholder") });
46
+ }
47
+ //#endregion
2
48
  //#region src/utils/firestore.ts
3
- function c(e) {
49
+ function snapshotToData(snapshot) {
4
50
  return {
5
- ...e.data(),
6
- id: e.id
51
+ ...snapshot.data(),
52
+ id: snapshot.id
7
53
  };
8
54
  }
9
- async function l(n, i, o, c, l) {
10
- let u = l.filter((e) => !!(e && !c.has(e.path)));
11
- for (let l = 0; l < u.length; l += 30) {
12
- let d = u.slice(l, l + 30);
13
- (await r(a(e(n, i), s(t(), "in", d.map((e) => e.id))))).forEach((e) => {
14
- let t = o(e);
15
- c.set(e.ref.path, t);
55
+ async function fetchItems(firestore, colName, changeMethod, cache, referenceArray) {
56
+ const missingRefs = referenceArray.filter((ref) => Boolean(ref && !cache.has(ref.path)));
57
+ const chunkSize = 30;
58
+ for (let i = 0; i < missingRefs.length; i += chunkSize) {
59
+ const chunk = missingRefs.slice(i, i + chunkSize);
60
+ (await getDocs(query(collection(firestore, colName), where(documentId(), "in", chunk.map((ref) => ref.id))))).forEach((snapshot) => {
61
+ const item = changeMethod(snapshot);
62
+ cache.set(snapshot.ref.path, item);
16
63
  });
17
64
  }
18
65
  }
19
- async function u(e, t, r) {
20
- let i = r.filter((e) => !!(e && !t.has(e.path)));
21
- await Promise.all(i.map(async (r) => {
22
- let i = e(await n(r));
23
- t.set(r.path, i);
66
+ async function fetchItemsByOne(changeMethod, cache, referenceArray) {
67
+ const missingRefs = referenceArray.filter((ref) => Boolean(ref && !cache.has(ref.path)));
68
+ await Promise.all(missingRefs.map(async (ref) => {
69
+ const item = changeMethod(await getDoc(ref));
70
+ cache.set(ref.path, item);
24
71
  }));
25
72
  }
26
- function d(e, t, n = {}) {
27
- let { cache: r = !0, onError: a } = n;
28
- return i(e, { includeMetadataChanges: !r }, (e) => {
29
- (r || !e.metadata.fromCache) && t(e);
30
- }, a);
73
+ function getSnapshots(ref, callback, options = {}) {
74
+ const { cache = true, onError } = options;
75
+ return onSnapshot(ref, { includeMetadataChanges: !cache }, (snapshot) => {
76
+ if (cache || !snapshot.metadata.fromCache) callback(snapshot);
77
+ }, onError);
31
78
  }
32
79
  //#endregion
33
80
  //#region src/utils/array.ts
34
- Array.prototype.mapNotNull = function(e) {
35
- return this.flatMap((t, n) => {
36
- let r = e(t, n);
37
- return r == null ? [] : [r];
81
+ Array.prototype.mapNotNull = function(fn) {
82
+ return this.flatMap((item, index) => {
83
+ const result = fn(item, index);
84
+ return result != null ? [result] : [];
38
85
  });
39
86
  };
40
87
  //#endregion
41
88
  //#region src/constant/firestore.ts
42
- var f = () => ({
43
- updateAt: o(),
44
- delete: !0
45
- }), p = () => ({
46
- updateAt: o(),
47
- delete: !1
89
+ var deleteItem = () => ({
90
+ "updateAt": serverTimestamp(),
91
+ "delete": true
92
+ });
93
+ var undeleteItem = () => ({
94
+ "updateAt": serverTimestamp(),
95
+ "delete": false
48
96
  });
49
97
  //#endregion
50
- export { f as deleteItem, l as fetchItems, u as fetchItemsByOne, d as getSnapshots, c as snapshotToData, p as undeleteItem };
98
+ export { CrossfadeImage, deleteItem, fetchItems, fetchItemsByOne, getSnapshots, snapshotToData, undeleteItem };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ienlab/react-library",
3
- "version": "0.4.0",
3
+ "version": "0.4.3",
4
4
  "description": "My React component library",
5
5
  "main": "./dist/my-library.cjs.js",
6
6
  "module": "./dist/my-library.es.js",
@@ -1 +0,0 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`firebase/firestore`);function t(e){return{...e.data(),id:e.id}}async function n(t,n,r,i,a){let o=a.filter(e=>!!(e&&!i.has(e.path)));for(let a=0;a<o.length;a+=30){let s=o.slice(a,a+30);(await(0,e.getDocs)((0,e.query)((0,e.collection)(t,n),(0,e.where)((0,e.documentId)(),`in`,s.map(e=>e.id))))).forEach(e=>{let t=r(e);i.set(e.ref.path,t)})}}async function r(t,n,r){let i=r.filter(e=>!!(e&&!n.has(e.path)));await Promise.all(i.map(async r=>{let i=t(await(0,e.getDoc)(r));n.set(r.path,i)}))}function i(t,n,r={}){let{cache:i=!0,onError:a}=r;return(0,e.onSnapshot)(t,{includeMetadataChanges:!i},e=>{(i||!e.metadata.fromCache)&&n(e)},a)}Array.prototype.mapNotNull=function(e){return this.flatMap((t,n)=>{let r=e(t,n);return r==null?[]:[r]})};var a=()=>({updateAt:(0,e.serverTimestamp)(),delete:!0}),o=()=>({updateAt:(0,e.serverTimestamp)(),delete:!1});exports.deleteItem=a,exports.fetchItems=n,exports.fetchItemsByOne=r,exports.getSnapshots=i,exports.snapshotToData=t,exports.undeleteItem=o;