@zhushanwen/pi-pending-notifications 0.5.2 → 0.5.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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/state.ts +19 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/pi-pending-notifications",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Cross-extension async operation registration/query mechanism for Pi.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -33,7 +33,7 @@
33
33
  "typebox": "*"
34
34
  },
35
35
  "dependencies": {
36
- "@zhushanwen/pi-extension-logger": "0.4.0"
36
+ "@zhushanwen/pi-extension-logger": "0.4.1"
37
37
  },
38
38
  "scripts": {
39
39
  "typecheck": "npx tsc --noEmit",
package/src/state.ts CHANGED
@@ -148,34 +148,33 @@ export function countActiveFromEntries(
148
148
  entries: unknown[],
149
149
  opts?: CountActiveOptions,
150
150
  ): CountActiveResult {
151
- const unregistered = new Set<string>();
152
- for (const raw of entries as EntryLike[]) {
153
- // S-10:entries 元素可能是 null/undefined(外部调用方/坏数据),
154
- // EntryLike 断言前先守卫,避免访问 raw.customType 抛 TypeError 炸掉差集判定。
155
- if (!raw || typeof raw !== "object") continue;
156
- if (raw.customType !== "pending:unregister") continue;
157
- const data = (raw.data ?? {}) as UnregisterEntryData;
158
- if (typeof data.id === "string") unregistered.add(data.id);
159
- }
151
+ // rebuildFromEntries 共用单趟扫描(S-10 守卫一致),分流 register/unregister
152
+ const { registerEntries, unregisteredIds } = scanPendingEntries(entries);
153
+ const active = filterActiveRegisters(registerEntries, unregisteredIds, opts);
154
+
155
+ return {
156
+ count: active.length,
157
+ ids: active.map((e) => e.id),
158
+ entries: active,
159
+ };
160
+ }
160
161
 
162
+ /** 差集过滤:跳过 id 非法 / 已注销 / 重复 register 的 entry,按 opts.types 过滤类型。 */
163
+ function filterActiveRegisters(
164
+ registerEntries: Array<{ data: RegisterEntryData }>,
165
+ unregisteredIds: Set<string>,
166
+ opts?: CountActiveOptions,
167
+ ): PendingEntry[] {
161
168
  const active: PendingEntry[] = [];
162
169
  const seen = new Set<string>();
163
- for (const raw of entries as EntryLike[]) {
164
- if (!raw || typeof raw !== "object") continue;
165
- if (raw.customType !== "pending:register") continue;
166
- const data = (raw.data ?? {}) as RegisterEntryData;
167
- if (typeof data.id !== "string" || unregistered.has(data.id) || seen.has(data.id)) continue;
170
+ for (const { data } of registerEntries) {
171
+ if (typeof data.id !== "string" || unregisteredIds.has(data.id) || seen.has(data.id)) continue;
168
172
  seen.add(data.id);
169
173
  const entry = normalizeRegisterEntry(data, "");
170
174
  if (opts?.types && !opts.types.includes(entry.type)) continue;
171
175
  active.push(entry);
172
176
  }
173
-
174
- return {
175
- count: active.length,
176
- ids: active.map((e) => e.id),
177
- entries: active,
178
- };
177
+ return active;
179
178
  }
180
179
 
181
180
  /** rebuildFromEntries 的结果:重建后的活跃列表 + 需要补注销的 entry */