@flowlist/js-core 3.0.8 → 3.0.10

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/dist/index.d.mts CHANGED
@@ -172,43 +172,18 @@ declare const initData: ({ getter, setter, func, type, query, api, uniqueKey, ca
172
172
  declare const loadMore: ({ getter, setter, query, type, func, api, uniqueKey, errorRetry, callback }: LoadMoreType) => Promise<void>;
173
173
  declare const updateState: ({ getter, setter, func, type, query, method, value, id, uniqueKey, changeKey }: UpdateStateType) => Promise<unknown>;
174
174
 
175
- /**
176
- * 判断数据是否为对象结果(即没有 result 字段)
177
- * 注意:这里我们假设 "对象结果" 指的是一个普通的对象,而不是 ApiResponse。
178
- */
175
+ declare const isArray: (data: unknown) => data is unknown[];
179
176
  declare const isObjectResult: (data: unknown) => data is Record<string, unknown>;
180
- /**
181
- * 生成默认字段
182
- */
183
177
  declare const generateDefaultField: (opts?: Partial<DefaultField>) => DefaultField;
184
- /**
185
- * 根据参数生成 field 的 namespace
186
- */
187
178
  declare const generateFieldName: ({ func, type, query }: InitDataParams) => string;
188
- /**
189
- * 根据 key 从 object 里拿 value
190
- */
191
179
  declare const getObjectDeepValue: (field: unknown, keys?: string | string[]) => unknown;
192
- /**
193
- * 安全地更新对象的深层值
194
- */
195
180
  declare const updateObjectDeepValue: (field: Record<string, unknown>, changeKey: string, value: unknown) => void;
196
181
  type ResultArrayType = KeyMap[];
197
182
  type ResultObjectType = Record<ObjectKey, KeyMap[]>;
198
183
  declare const searchValueByKey: (result: ResultArrayType | ResultObjectType, id: ObjectKey, key: string) => unknown;
199
184
  declare const computeMatchedItemIndex: (itemId: ObjectKey, fieldArr: ResultArrayType, changingKey: string) => number;
200
185
  declare const combineArrayData: (fieldArray: ResultArrayType, value: ResultArrayType | Record<ObjectKey, KeyMap>, changingKey: string) => void;
201
- /**
202
- * 判断参数是否为数组
203
- */
204
- declare const isArray: (data: unknown) => data is unknown[];
205
- /**
206
- * 设置一个响应式的数据到对象上
207
- */
208
186
  declare const setReactivityField: (field: DefaultField, key: FieldKeys, value: unknown, type: FetchType, insertBefore: boolean) => void;
209
- /**
210
- * 计算一个数据列的长度
211
- */
212
187
  declare const computeResultLength: (data: unknown) => number;
213
188
  declare const generateRequestParams: ({ field, uniqueKey, query, type }: GenerateParamsType) => GenerateParamsResp;
214
189
 
package/dist/index.d.ts CHANGED
@@ -172,43 +172,18 @@ declare const initData: ({ getter, setter, func, type, query, api, uniqueKey, ca
172
172
  declare const loadMore: ({ getter, setter, query, type, func, api, uniqueKey, errorRetry, callback }: LoadMoreType) => Promise<void>;
173
173
  declare const updateState: ({ getter, setter, func, type, query, method, value, id, uniqueKey, changeKey }: UpdateStateType) => Promise<unknown>;
174
174
 
175
- /**
176
- * 判断数据是否为对象结果(即没有 result 字段)
177
- * 注意:这里我们假设 "对象结果" 指的是一个普通的对象,而不是 ApiResponse。
178
- */
175
+ declare const isArray: (data: unknown) => data is unknown[];
179
176
  declare const isObjectResult: (data: unknown) => data is Record<string, unknown>;
180
- /**
181
- * 生成默认字段
182
- */
183
177
  declare const generateDefaultField: (opts?: Partial<DefaultField>) => DefaultField;
184
- /**
185
- * 根据参数生成 field 的 namespace
186
- */
187
178
  declare const generateFieldName: ({ func, type, query }: InitDataParams) => string;
188
- /**
189
- * 根据 key 从 object 里拿 value
190
- */
191
179
  declare const getObjectDeepValue: (field: unknown, keys?: string | string[]) => unknown;
192
- /**
193
- * 安全地更新对象的深层值
194
- */
195
180
  declare const updateObjectDeepValue: (field: Record<string, unknown>, changeKey: string, value: unknown) => void;
196
181
  type ResultArrayType = KeyMap[];
197
182
  type ResultObjectType = Record<ObjectKey, KeyMap[]>;
198
183
  declare const searchValueByKey: (result: ResultArrayType | ResultObjectType, id: ObjectKey, key: string) => unknown;
199
184
  declare const computeMatchedItemIndex: (itemId: ObjectKey, fieldArr: ResultArrayType, changingKey: string) => number;
200
185
  declare const combineArrayData: (fieldArray: ResultArrayType, value: ResultArrayType | Record<ObjectKey, KeyMap>, changingKey: string) => void;
201
- /**
202
- * 判断参数是否为数组
203
- */
204
- declare const isArray: (data: unknown) => data is unknown[];
205
- /**
206
- * 设置一个响应式的数据到对象上
207
- */
208
186
  declare const setReactivityField: (field: DefaultField, key: FieldKeys, value: unknown, type: FetchType, insertBefore: boolean) => void;
209
- /**
210
- * 计算一个数据列的长度
211
- */
212
187
  declare const computeResultLength: (data: unknown) => number;
213
188
  declare const generateRequestParams: ({ field, uniqueKey, query, type }: GenerateParamsType) => GenerateParamsResp;
214
189
 
@@ -59,6 +59,42 @@ var FlowList = (function (exports) {
59
59
  };
60
60
 
61
61
  // src/utils.ts
62
+ var isArray = (data) => {
63
+ return Array.isArray(data);
64
+ };
65
+ var stableSerialize = (value) => {
66
+ if (value === null || typeof value !== "object") {
67
+ return String(value);
68
+ }
69
+ try {
70
+ if (Array.isArray(value)) {
71
+ return JSON.stringify(value);
72
+ }
73
+ const keys = Object.keys(value).sort();
74
+ const obj = {};
75
+ for (const k of keys) {
76
+ obj[k] = value[k];
77
+ }
78
+ return JSON.stringify(obj);
79
+ } catch {
80
+ return "[Circular Object/Value]";
81
+ }
82
+ };
83
+ var extractUniqueKey = (item, uniqueKey) => {
84
+ if (typeof item !== "object" || item === null) return void 0;
85
+ const changing = uniqueKey || enum_default.DEFAULT_UNIQUE_KEY_NAME;
86
+ const val = item[changing] ?? void 0;
87
+ if (typeof val === "string" || typeof val === "number") {
88
+ return val;
89
+ }
90
+ if (typeof changing === "string" && changing.includes(".")) {
91
+ const deepVal = getObjectDeepValue(item, changing);
92
+ if (typeof deepVal === "string" || typeof deepVal === "number") {
93
+ return deepVal;
94
+ }
95
+ }
96
+ return void 0;
97
+ };
62
98
  var isObjectResult = (data) => {
63
99
  if (typeof data !== "object" || data === null) {
64
100
  return false;
@@ -84,11 +120,11 @@ var FlowList = (function (exports) {
84
120
  type,
85
121
  query = {}
86
122
  }) => {
87
- const funcName = typeof func === "string" ? func : `api-${Math.random().toString(36).substring(2)}`;
123
+ const funcName = typeof func === "string" ? func : (typeof func === "function" ? func.name : void 0) || `api-${Math.random().toString(36).substring(2, 8)}`;
88
124
  const fetchType = type || "auto";
89
125
  let result = `${funcName}-${fetchType}`;
90
126
  const filteredKeys = Object.keys(query).filter(
91
- (key) => !["undefined", "function"].includes(typeof query[key]) && ![
127
+ (key) => query[key] !== void 0 && typeof query[key] !== "function" && ![
92
128
  "page",
93
129
  "is_up",
94
130
  "since_id",
@@ -97,12 +133,19 @@ var FlowList = (function (exports) {
97
133
  "__reload__"
98
134
  ].includes(key)
99
135
  );
100
- filteredKeys.sort().forEach((key) => {
136
+ filteredKeys.sort();
137
+ const querySuffix = filteredKeys.map((key) => {
101
138
  const value = query[key];
102
- const safeValue = typeof value === "object" ? JSON.stringify(value) : String(value);
139
+ let safeValue;
140
+ if (typeof value === "object" && value !== null) {
141
+ safeValue = stableSerialize(value);
142
+ } else {
143
+ safeValue = String(value);
144
+ }
103
145
  const encoded = encodeURIComponent(safeValue);
104
- result += `-${key}-${encoded}`;
105
- });
146
+ return `-${key}-${encoded}`;
147
+ }).join("");
148
+ result += querySuffix;
106
149
  return result;
107
150
  };
108
151
  var getObjectDeepValue = (field, keys = "") => {
@@ -125,7 +168,7 @@ var FlowList = (function (exports) {
125
168
  const lastKey = keys.pop();
126
169
  let current = field;
127
170
  for (const key of keys) {
128
- if (current == null || typeof current !== "object") {
171
+ if (current[key] == null || typeof current[key] !== "object") {
129
172
  current[key] = {};
130
173
  }
131
174
  current = current[key];
@@ -157,14 +200,21 @@ var FlowList = (function (exports) {
157
200
  return -1;
158
201
  };
159
202
  var combineArrayData = (fieldArray, value, changingKey) => {
203
+ const fieldArrayMap = /* @__PURE__ */ new Map();
204
+ for (let i = 0; i < fieldArray.length; i++) {
205
+ const item = fieldArray[i];
206
+ if (typeof item !== "object" || item === null) continue;
207
+ const id = getObjectDeepValue(item, changingKey);
208
+ if (id !== void 0) {
209
+ fieldArrayMap.set(String(id), i);
210
+ }
211
+ }
160
212
  if (isArray(value)) {
161
213
  for (const col of value) {
162
214
  if (typeof col !== "object" || col === null) continue;
163
215
  const stringifyId = String(getObjectDeepValue(col, changingKey));
164
- const index = fieldArray.findIndex(
165
- (item) => typeof item === "object" && item !== null && String(getObjectDeepValue(item, changingKey)) === stringifyId
166
- );
167
- if (index !== -1) {
216
+ const index = fieldArrayMap.get(stringifyId);
217
+ if (index !== void 0 && index !== -1) {
168
218
  fieldArray[index] = { ...fieldArray[index], ...col };
169
219
  }
170
220
  }
@@ -172,48 +222,53 @@ var FlowList = (function (exports) {
172
222
  for (const [uniqueId, col] of Object.entries(value)) {
173
223
  if (typeof col !== "object" || col === null) continue;
174
224
  const stringifyId = String(uniqueId);
175
- const index = fieldArray.findIndex(
176
- (item) => typeof item === "object" && item !== null && String(getObjectDeepValue(item, changingKey)) === stringifyId
177
- );
178
- if (index !== -1) {
225
+ const index = fieldArrayMap.get(stringifyId);
226
+ if (index !== void 0 && index !== -1) {
179
227
  fieldArray[index] = { ...fieldArray[index], ...col };
180
228
  }
181
229
  }
182
230
  }
183
231
  };
184
- var isArray = (data) => {
185
- return Array.isArray(data);
186
- };
187
232
  var setReactivityField = (field, key, value, type, insertBefore) => {
188
233
  if (type === enum_default.FETCH_TYPE.PAGINATION) {
189
234
  field[key] = value;
190
235
  return;
191
236
  }
192
- if (isArray(value)) {
193
- const current = field[key];
194
- const currentArr = isArray(current) ? current : [];
195
- const newValue = insertBefore ? value.concat(currentArr) : currentArr.concat(value);
196
- field[key] = newValue;
197
- return;
198
- }
199
237
  if (key !== enum_default.FIELD_DATA.RESULT_KEY) {
200
- field[key] = value;
238
+ if (isArray(value)) {
239
+ const current = field[key];
240
+ const currentArr = isArray(current) ? current : [];
241
+ const newValue = insertBefore ? [...value, ...currentArr] : [...currentArr, ...value];
242
+ field[key] = newValue;
243
+ } else {
244
+ field[key] = value;
245
+ }
201
246
  return;
202
247
  }
203
248
  const resultField = field.result;
249
+ const valueObj = value;
250
+ if (isArray(value)) {
251
+ const currentArr = isArray(resultField) ? resultField : [];
252
+ const newValue = insertBefore ? [...value, ...currentArr] : [...currentArr, ...value];
253
+ field.result = newValue;
254
+ return;
255
+ }
256
+ let target = resultField;
204
257
  if (isArray(resultField)) {
205
- field.result = {};
258
+ target = {};
259
+ field.result = target;
260
+ } else if (typeof resultField !== "object" || resultField === null) {
261
+ target = {};
262
+ field.result = target;
206
263
  }
207
- const valueObj = value;
208
- const target = field.result;
209
264
  Object.keys(valueObj).forEach((subKey) => {
210
265
  const existing = target[subKey];
211
266
  const incoming = valueObj[subKey];
212
267
  if (existing !== void 0) {
213
268
  if (insertBefore) {
214
- target[subKey] = isArray(incoming) && isArray(existing) ? incoming.concat(existing) : incoming;
269
+ target[subKey] = isArray(incoming) && isArray(existing) ? [...incoming, ...existing] : incoming;
215
270
  } else {
216
- target[subKey] = isArray(existing) && isArray(incoming) ? existing.concat(incoming) : incoming;
271
+ target[subKey] = isArray(existing) && isArray(incoming) ? [...existing, ...incoming] : incoming;
217
272
  }
218
273
  } else {
219
274
  target[subKey] = incoming;
@@ -225,15 +280,27 @@ var FlowList = (function (exports) {
225
280
  return data.length;
226
281
  }
227
282
  if (data && typeof data === "object") {
228
- return Object.values(data).reduce((acc, val) => {
283
+ let acc = 0;
284
+ for (const val of Object.values(data)) {
229
285
  if (isArray(val)) {
230
- return acc + val.length;
286
+ acc += val.length;
231
287
  }
232
- return acc;
233
- }, 0);
288
+ }
289
+ return acc;
234
290
  }
235
291
  return 0;
236
292
  };
293
+ var getSeenIdsString = (arr, uniqueKey) => {
294
+ if (!isArray(arr)) return "";
295
+ const ids = [];
296
+ for (const item of arr) {
297
+ const id = extractUniqueKey(item, uniqueKey);
298
+ if (id !== void 0) {
299
+ ids.push(id);
300
+ }
301
+ }
302
+ return ids.join(",");
303
+ };
237
304
  var generateRequestParams = ({
238
305
  field,
239
306
  uniqueKey,
@@ -241,20 +308,14 @@ var FlowList = (function (exports) {
241
308
  type
242
309
  }) => {
243
310
  const result = {};
244
- const changing = uniqueKey || enum_default.DEFAULT_UNIQUE_KEY_NAME;
245
311
  const isFetched = field.fetched;
246
312
  const getSafeObjectKey = (item) => {
247
- if (typeof item !== "object" || item === null) return void 0;
248
- const val = getObjectDeepValue(item, changing);
249
- if (typeof val === "string" || typeof val === "number") {
250
- return val;
251
- }
252
- return void 0;
313
+ return extractUniqueKey(item, uniqueKey);
253
314
  };
254
315
  if (isFetched) {
255
316
  if (type === enum_default.FETCH_TYPE.AUTO) {
256
317
  if (isArray(field.result)) {
257
- result.seen_ids = field.result.map((item) => getSafeObjectKey(item)).filter((id) => id !== void 0).join(",");
318
+ result.seen_ids = getSeenIdsString(field.result, uniqueKey);
258
319
  const targetIndex = query.is_up ? 0 : field.result.length - 1;
259
320
  const targetItem = field.result[targetIndex];
260
321
  result.since_id = getSafeObjectKey(targetItem);
@@ -263,7 +324,7 @@ var FlowList = (function (exports) {
263
324
  result.page = typeof query.page === "number" ? query.page : field.page + 1;
264
325
  } else if (type === enum_default.FETCH_TYPE.HAS_LOADED_IDS) {
265
326
  if (isArray(field.result)) {
266
- result.seen_ids = field.result.map((item) => getSafeObjectKey(item)).filter((id) => id !== void 0).join(",");
327
+ result.seen_ids = getSeenIdsString(field.result, uniqueKey);
267
328
  }
268
329
  } else if (type === enum_default.FETCH_TYPE.SINCE_FIRST_OR_END_ID) {
269
330
  if (isArray(field.result)) {
@@ -386,7 +447,6 @@ var FlowList = (function (exports) {
386
447
  getter,
387
448
  setter,
388
449
  func,
389
- // string only
390
450
  type,
391
451
  query,
392
452
  opts
@@ -412,7 +472,6 @@ var FlowList = (function (exports) {
412
472
  getter,
413
473
  setter,
414
474
  func,
415
- // string | function
416
475
  type,
417
476
  query,
418
477
  api,
@@ -446,7 +505,7 @@ var FlowList = (function (exports) {
446
505
  type
447
506
  });
448
507
  const getData = () => {
449
- const loadData = () => new Promise((res, rej) => {
508
+ const apiCaller = () => new Promise((res, rej) => {
450
509
  const getDataFromAPI = () => {
451
510
  const funcCaller = typeof func === "string" && api ? api[func] : func;
452
511
  if (typeof funcCaller === "function") {
@@ -458,7 +517,7 @@ var FlowList = (function (exports) {
458
517
  };
459
518
  getDataFromAPI();
460
519
  });
461
- loadData().then((data) => {
520
+ apiCaller().then((data) => {
462
521
  const setData = () => {
463
522
  SET_DATA({
464
523
  getter,
@@ -473,14 +532,13 @@ var FlowList = (function (exports) {
473
532
  callback({
474
533
  params,
475
534
  data,
476
- // <-- 'data' is now properly in scope
477
535
  refresh: doRefresh
478
536
  });
479
537
  }
480
538
  resolve();
481
539
  });
482
540
  };
483
- if (needReset) {
541
+ if (doRefresh && !needReset) {
484
542
  setter({
485
543
  key: fieldName,
486
544
  type: enum_default.SETTER_TYPE.RESET,
@@ -492,19 +550,20 @@ var FlowList = (function (exports) {
492
550
  }
493
551
  }).catch(reject);
494
552
  };
495
- if (!dontFetch && !needReset) {
553
+ if (doRefresh && !needReset) {
554
+ getData();
555
+ } else {
496
556
  setter({
497
557
  key: fieldName,
498
558
  type: enum_default.SETTER_TYPE.RESET,
499
559
  value: {
500
560
  ...generateDefaultField(),
501
561
  loading: true,
502
- error: null
562
+ error: null,
563
+ extra: null
503
564
  },
504
565
  callback: getData
505
566
  });
506
- } else {
507
- getData();
508
567
  }
509
568
  });
510
569
  var loadMore = ({