@pkcprotocol/pkc-js 0.0.112 → 0.0.113

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 (32) hide show
  1. package/README.md +4 -4
  2. package/dist/browser/generated-version.d.ts +1 -1
  3. package/dist/browser/generated-version.js +1 -1
  4. package/dist/browser/pages/pkc-js-page-sorts/active.js +3 -2
  5. package/dist/browser/pages/pkc-js-page-sorts/active.js.map +1 -1
  6. package/dist/browser/publications/comment/schema.js +4 -4
  7. package/dist/browser/publications/comment/schema.js.map +1 -1
  8. package/dist/browser/runtime/node/community/db-handler.d.ts +1 -0
  9. package/dist/browser/runtime/node/community/db-handler.js +50 -35
  10. package/dist/browser/runtime/node/community/db-handler.js.map +1 -1
  11. package/dist/browser/version.js +1 -1
  12. package/dist/bundled/bundle-manifest.json +43 -43
  13. package/dist/bundled/chunks/{helia-for-pkc-DDLK491v.js → helia-for-pkc-DoOp7t8V.js} +33 -33
  14. package/dist/bundled/chunks/{local-community-kjNJHOud.js → local-community-CFX753RE.js} +1 -1
  15. package/dist/bundled/chunks/{local-community-DJGHwkuK.js → local-community-CaV30etW.js} +66 -55
  16. package/dist/bundled/chunks/{node-C_wuNW9S.js → node-gyqBss4j.js} +5 -5
  17. package/dist/bundled/chunks/{rpc-local-community-BHSnYv5v.js → rpc-local-community-DWv8wZMB.js} +1 -1
  18. package/dist/bundled/chunks/{util-C68VdI47.js → util-B9JenRyE.js} +2 -2
  19. package/dist/bundled/chunks/{util-BuDJJAAP.js → util-CH8WrVZq.js} +1 -1
  20. package/dist/bundled/index.js +1 -1
  21. package/dist/bundled/rpc/src/index.js +4 -4
  22. package/dist/node/generated-version.d.ts +1 -1
  23. package/dist/node/generated-version.js +1 -1
  24. package/dist/node/pages/pkc-js-page-sorts/active.js +3 -2
  25. package/dist/node/pages/pkc-js-page-sorts/active.js.map +1 -1
  26. package/dist/node/publications/comment/schema.js +4 -4
  27. package/dist/node/publications/comment/schema.js.map +1 -1
  28. package/dist/node/runtime/node/community/db-handler.d.ts +1 -0
  29. package/dist/node/runtime/node/community/db-handler.js +50 -35
  30. package/dist/node/runtime/node/community/db-handler.js.map +1 -1
  31. package/dist/node/version.js +1 -1
  32. package/package.json +1 -1
@@ -1598,14 +1598,19 @@ export class DbHandler {
1598
1598
  _collectCommentsToBeUpdated() {
1599
1599
  const windowed = this._buildWindowedReplySortArms(timestamp());
1600
1600
  const notPending = (alias) => `(${alias}.pendingApproval IS NULL OR ${alias}.pendingApproval != 1)`;
1601
- // A child that counts towards its parent's childCount: has a CommentUpdate, not removed, not deleted by its author
1601
+ const countedChildAddress = this._communityAddressClauseNamed("c", "countedChild");
1602
+ // A child that counts towards its parent's childCount: has a CommentUpdate and this community's address, not
1603
+ // removed, not deleted by its author, not disapproved (the rule _queryReplyCountsByParentCids and
1604
+ // _queryLastChildCidsByParentCids apply, or the parent is re-flagged every cycle)
1602
1605
  const countedChild = `
1603
1606
  FROM ${TABLES.COMMENTS} c
1604
1607
  JOIN ${TABLES.COMMENT_UPDATES} cu_child ON c.cid = cu_child.cid
1605
1608
  WHERE c.parentCid IS NOT NULL
1609
+ AND ${countedChildAddress.clause}
1606
1610
  AND ${notPending("c")}
1607
1611
  AND (cu_child.removed IS NOT 1 AND cu_child.removed IS NOT TRUE)
1608
- AND (json_extract(cu_child.edit, '$.deleted') IS NULL OR json_extract(cu_child.edit, '$.deleted') != 1)`;
1612
+ AND (json_extract(cu_child.edit, '$.deleted') IS NULL OR json_extract(cu_child.edit, '$.deleted') != 1)
1613
+ AND COALESCE(cu_child.approved, 1) != 0`;
1609
1614
  const insert = `INSERT OR IGNORE INTO ${COMMENTS_TO_UPDATE_TEMP_TABLE}`;
1610
1615
  const arms = [
1611
1616
  `${insert}
@@ -1637,7 +1642,6 @@ export class DbHandler {
1637
1642
  WITH last_child_rowids AS (
1638
1643
  SELECT c.parentCid AS cid, MAX(c.rowid) AS last_child_rowid
1639
1644
  ${countedChild}
1640
- AND COALESCE(cu_child.approved, 1) != 0
1641
1645
  GROUP BY c.parentCid
1642
1646
  )
1643
1647
  SELECT parent.rowid
@@ -1685,9 +1689,11 @@ export class DbHandler {
1685
1689
  )
1686
1690
  SELECT id FROM parent_chain`
1687
1691
  ];
1692
+ const allParams = { ...windowed.params, ...countedChildAddress.params };
1688
1693
  for (const arm of arms) {
1689
- // Each statement is bound only to the named parameters it mentions (the windowed arms' window bounds)
1690
- const params = Object.fromEntries(Object.entries(windowed.params).filter(([name]) => arm.includes(`:${name}`)));
1694
+ // Each statement is bound only to the named parameters it mentions (the windowed arms' window bounds, the
1695
+ // counted-child address)
1696
+ const params = Object.fromEntries(Object.entries(allParams).filter(([name]) => arm.includes(`:${name}`)));
1691
1697
  this._prepareCached(arm).run(params);
1692
1698
  }
1693
1699
  }
@@ -2294,79 +2300,88 @@ export class DbHandler {
2294
2300
  }
2295
2301
  return result;
2296
2302
  }
2297
- // replyCount and childCount of every parent in one recursive walk anchored on all of them: a descendant counts
2298
- // when every comment on the path from the parent has a CommentUpdate, this community's address, and is neither
2299
- // removed nor deleted; childCount is the level-1 part of the same walk.
2303
+ // Whether a comment in a reply walk is present (neither removed, deleted nor disapproved), over the cu and d aliases
2304
+ // the walks join. A comment that is not present is skipped by the counts but still walked through: reply pages keep
2305
+ // it as a tombstone, so the present replies under it are still part of the thread (#405). A disapproved comment
2306
+ // never has replies under it, since publishing under a pending or disapproved comment is rejected.
2307
+ _replyWalkPresentExpression() {
2308
+ return `CASE WHEN (cu.removed IS NOT 1 AND cu.removed IS NOT TRUE) AND (d.deleted_flag IS NULL OR d.deleted_flag != 1) AND COALESCE(cu.approved, 1) != 0 THEN 1 ELSE 0 END`;
2309
+ }
2310
+ // replyCount and childCount of every parent in one recursive walk anchored on all of them: the walk follows every
2311
+ // descendant whose path from the parent has a CommentUpdate and this community's address, and a descendant counts
2312
+ // when it is also present (neither removed, deleted nor disapproved); childCount is the level-1 part of the same count.
2300
2313
  _queryReplyCountsByParentCids(parentCids) {
2301
2314
  const result = new Map();
2302
2315
  const { clause: addrClause, params: addrParams } = this._communityAddressClause("c");
2303
- const passes = `${addrClause} AND (cu.removed IS NOT 1 AND cu.removed IS NOT TRUE) AND (d.deleted_flag IS NULL OR d.deleted_flag != 1)`;
2316
+ const present = this._replyWalkPresentExpression();
2304
2317
  const deletedLookup = `(SELECT cid, json_extract(edit, '$.deleted') AS deleted_flag FROM ${TABLES.COMMENT_UPDATES})`;
2305
2318
  for (const { placeholders, params } of this._cidChunks(parentCids, addrParams.length * 2)) {
2306
- const rows = this._prepareCached(`WITH RECURSIVE descendants(root, cid, level) AS (
2307
- SELECT c.parentCid, c.cid, 1 FROM ${TABLES.COMMENTS} c
2319
+ const rows = this._prepareCached(`WITH RECURSIVE descendants(root, cid, level, present) AS (
2320
+ SELECT c.parentCid, c.cid, 1, ${present} FROM ${TABLES.COMMENTS} c
2308
2321
  INNER JOIN ${TABLES.COMMENT_UPDATES} cu ON c.cid = cu.cid
2309
2322
  LEFT JOIN ${deletedLookup} AS d ON c.cid = d.cid
2310
- WHERE c.parentCid IN (${placeholders}) AND ${passes}
2323
+ WHERE c.parentCid IN (${placeholders}) AND ${addrClause}
2311
2324
  UNION ALL
2312
- SELECT desc_nodes.root, c.cid, desc_nodes.level + 1 FROM ${TABLES.COMMENTS} c
2325
+ SELECT desc_nodes.root, c.cid, desc_nodes.level + 1, ${present} FROM ${TABLES.COMMENTS} c
2313
2326
  INNER JOIN ${TABLES.COMMENT_UPDATES} cu ON c.cid = cu.cid
2314
2327
  LEFT JOIN ${deletedLookup} AS d ON c.cid = d.cid
2315
2328
  JOIN descendants desc_nodes ON c.parentCid = desc_nodes.cid
2316
- WHERE ${passes}
2329
+ WHERE ${addrClause}
2317
2330
  )
2318
- SELECT root, COUNT(*) AS replyCount, SUM(CASE WHEN level = 1 THEN 1 ELSE 0 END) AS childCount
2331
+ SELECT root, SUM(present) AS replyCount, SUM(CASE WHEN level = 1 THEN present ELSE 0 END) AS childCount
2319
2332
  FROM descendants GROUP BY root`).all(...params, ...addrParams, ...addrParams);
2320
2333
  for (const row of rows)
2321
2334
  result.set(row.root, { replyCount: row.replyCount, childCount: row.childCount });
2322
2335
  }
2323
2336
  return result;
2324
2337
  }
2325
- // lastReplyTimestamp of every parent: the newest timestamp under it. A direct reply counts unless it is pending or
2326
- // disapproved (a reply with no CommentUpdate yet counts); a deeper one also needs a CommentUpdate, this
2327
- // community's address and to be neither removed nor deleted, and so does every comment on its path.
2338
+ // lastReplyTimestamp of every parent: the newest timestamp among the replies replyCount counts, with the walk further
2339
+ // narrowed to comments that are not pending. A removed, deleted or disapproved reply does not bump its thread (#403),
2340
+ // but the present replies under it do (#405).
2328
2341
  _queryLastReplyTimestampsByParentCids(parentCids) {
2329
2342
  const result = new Map();
2330
2343
  const { clause: addrClause, params: addrParams } = this._communityAddressClause("c");
2331
- for (const { placeholders, params } of this._cidChunks(parentCids, addrParams.length)) {
2332
- const rows = this._prepareCached(`WITH RECURSIVE descendants(root, cid, timestamp) AS (
2333
- SELECT c.parentCid, c.cid, c.timestamp FROM ${TABLES.COMMENTS} c
2334
- LEFT JOIN ${TABLES.COMMENT_UPDATES} cu ON cu.cid = c.cid
2335
- WHERE c.parentCid IN (${placeholders})
2336
- AND COALESCE(cu.approved, 1) != 0
2337
- AND (c.pendingApproval IS NULL OR c.pendingApproval != 1)
2344
+ const walked = `${addrClause} AND (c.pendingApproval IS NULL OR c.pendingApproval != 1)`;
2345
+ const present = this._replyWalkPresentExpression();
2346
+ const deletedLookup = `(SELECT cid, json_extract(edit, '$.deleted') AS deleted_flag FROM ${TABLES.COMMENT_UPDATES})`;
2347
+ for (const { placeholders, params } of this._cidChunks(parentCids, addrParams.length * 2)) {
2348
+ const rows = this._prepareCached(`WITH RECURSIVE descendants(root, cid, timestamp, present) AS (
2349
+ SELECT c.parentCid, c.cid, c.timestamp, ${present} FROM ${TABLES.COMMENTS} c
2350
+ INNER JOIN ${TABLES.COMMENT_UPDATES} cu ON c.cid = cu.cid
2351
+ LEFT JOIN ${deletedLookup} AS d ON c.cid = d.cid
2352
+ WHERE c.parentCid IN (${placeholders}) AND ${walked}
2338
2353
  UNION ALL
2339
- SELECT desc_nodes.root, c.cid, c.timestamp FROM ${TABLES.COMMENTS} c
2354
+ SELECT desc_nodes.root, c.cid, c.timestamp, ${present} FROM ${TABLES.COMMENTS} c
2340
2355
  INNER JOIN ${TABLES.COMMENT_UPDATES} cu ON c.cid = cu.cid
2341
- LEFT JOIN (SELECT cid, json_extract(edit, '$.deleted') AS deleted_flag FROM ${TABLES.COMMENT_UPDATES}) AS d ON c.cid = d.cid
2356
+ LEFT JOIN ${deletedLookup} AS d ON c.cid = d.cid
2342
2357
  JOIN descendants desc_nodes ON c.parentCid = desc_nodes.cid
2343
- WHERE ${addrClause} AND (cu.removed IS NOT 1 AND cu.removed IS NOT TRUE) AND (d.deleted_flag IS NULL OR d.deleted_flag != 1)
2344
- AND COALESCE(cu.approved, 1) != 0
2345
- AND (c.pendingApproval IS NULL OR c.pendingApproval != 1)
2358
+ WHERE ${walked}
2346
2359
  )
2347
- SELECT root, MAX(timestamp) AS maxTimestamp FROM descendants GROUP BY root`).all(...params, ...addrParams);
2360
+ SELECT root, MAX(CASE WHEN present = 1 THEN timestamp END) AS maxTimestamp FROM descendants GROUP BY root`).all(...params, ...addrParams, ...addrParams);
2348
2361
  for (const row of rows)
2349
2362
  if (row.maxTimestamp !== null)
2350
2363
  result.set(row.root, row.maxTimestamp);
2351
2364
  }
2352
2365
  return result;
2353
2366
  }
2354
- // lastChildCid of every parent: its newest direct reply that has a CommentUpdate and is not pending, disapproved,
2355
- // removed or deleted (MAX(rowid) with the bare cid column: SQLite returns the cid of that row).
2367
+ // lastChildCid of every parent: its newest direct reply that has a CommentUpdate and this community's address and is
2368
+ // not pending, disapproved, removed or deleted (MAX(rowid) with the bare cid column: SQLite returns the cid of that row).
2356
2369
  _queryLastChildCidsByParentCids(parentCids) {
2357
2370
  const result = new Map();
2358
- for (const { placeholders, params } of this._cidChunks(parentCids)) {
2371
+ const { clause: addrClause, params: addrParams } = this._communityAddressClause("c");
2372
+ for (const { placeholders, params } of this._cidChunks(parentCids, addrParams.length)) {
2359
2373
  const rows = this._prepareCached(`SELECT c.parentCid AS parentCid, c.cid AS cid, MAX(c.rowid) AS lastRowid FROM ${TABLES.COMMENTS} c
2360
2374
  INNER JOIN ${TABLES.COMMENT_UPDATES} cu ON cu.cid = c.cid
2361
2375
  LEFT JOIN (
2362
2376
  SELECT cid, json_extract(edit, '$.deleted') AS deleted_flag FROM ${TABLES.COMMENT_UPDATES}
2363
2377
  ) deleted_lookup ON deleted_lookup.cid = c.cid
2364
2378
  WHERE c.parentCid IN (${placeholders})
2379
+ AND ${addrClause}
2365
2380
  AND (c.pendingApproval IS NULL OR c.pendingApproval != 1)
2366
2381
  AND COALESCE(cu.approved, 1) != 0
2367
2382
  AND (cu.removed IS NOT 1 AND cu.removed IS NOT TRUE)
2368
2383
  AND (deleted_lookup.deleted_flag IS NULL OR deleted_lookup.deleted_flag != 1)
2369
- GROUP BY c.parentCid`).all(...params);
2384
+ GROUP BY c.parentCid`).all(...params, ...addrParams);
2370
2385
  for (const row of rows)
2371
2386
  result.set(row.parentCid, row.cid);
2372
2387
  }