nostr-idb 2.1.6 → 2.2.0

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/README.md CHANGED
@@ -149,6 +149,11 @@ const db = await openDB("events");
149
149
 
150
150
  const cacheRelay = new CacheRelay(db);
151
151
 
152
+ // optionally filter out events before they are written to the database
153
+ cacheRelay.core.writeQueue.processEvents = async (events) => {
154
+ return events.filter((event) => event.content.includes("gm"));
155
+ };
156
+
152
157
  for (let event of events) {
153
158
  cacheRelay.publish(event);
154
159
  }
@@ -5,6 +5,8 @@ export declare class WriteQueue {
5
5
  private queuedIds;
6
6
  private eventQueue;
7
7
  private lastUsedQueue;
8
+ /** Called for each chunk of events before they are written to the database */
9
+ processEvents: ((events: NostrEvent[]) => Promise<NostrEvent[] | void>) | null;
8
10
  constructor(db: NostrIDB);
9
11
  addEvent(event: NostrEvent): void;
10
12
  addEvents(events: NostrEvent[]): void;
@@ -7,6 +7,8 @@ export class WriteQueue {
7
7
  queuedIds = new Set();
8
8
  eventQueue = [];
9
9
  lastUsedQueue = new Set();
10
+ /** Called for each chunk of events before they are written to the database */
11
+ processEvents = null;
10
12
  constructor(db) {
11
13
  this.db = db;
12
14
  }
@@ -36,7 +38,7 @@ export class WriteQueue {
36
38
  }
37
39
  async flush(count = 1000) {
38
40
  if (this.eventQueue.length > 0) {
39
- const events = [];
41
+ let events = [];
40
42
  for (let i = 0; i < count; i++) {
41
43
  const event = this.eventQueue.shift();
42
44
  if (!event)
@@ -44,6 +46,9 @@ export class WriteQueue {
44
46
  events.push(event);
45
47
  this.queuedIds.delete(event.id);
46
48
  }
49
+ if (this.processEvents) {
50
+ events = (await this.processEvents(events)) || events;
51
+ }
47
52
  await addEvents(this.db, events);
48
53
  log(`Wrote ${events.length} to database`);
49
54
  if (this.eventQueue.length > 0)
@@ -1,4 +1,6 @@
1
1
  import { Event, Filter } from "nostr-tools";
2
+ import { WriteQueue } from "../cache/write-queue.js";
3
+ import { IndexCache } from "../cache/index-cache.js";
2
4
  import { NostrIDB } from "../database/schema.js";
3
5
  export type SubscriptionOptions = {
4
6
  id?: string;
@@ -26,17 +28,18 @@ export type RelayCoreOptions = {
26
28
  };
27
29
  /** Main class that implements the relay logic */
28
30
  export declare class RelayCore {
29
- private options;
30
- private writeInterval?;
31
+ options: Required<RelayCoreOptions>;
32
+ running: boolean;
33
+ private writeTimeout?;
31
34
  private pruneInterval?;
32
- get running(): boolean;
33
- private eventMap;
34
- private writeQueue;
35
- private indexCache;
35
+ eventMap: Map<string, Event>;
36
+ writeQueue: WriteQueue;
37
+ indexCache: IndexCache;
36
38
  db: NostrIDB;
37
39
  baseEoseTimeout: number;
38
40
  private subscriptions;
39
41
  constructor(db: NostrIDB, opts?: RelayCoreOptions);
42
+ private flush;
40
43
  start(): Promise<void>;
41
44
  stop(): Promise<void>;
42
45
  publish(event: Event): Promise<string>;
@@ -18,11 +18,9 @@ const log = logger.extend("relay");
18
18
  /** Main class that implements the relay logic */
19
19
  export class RelayCore {
20
20
  options;
21
- writeInterval;
21
+ running = false;
22
+ writeTimeout;
22
23
  pruneInterval;
23
- get running() {
24
- return !!this.writeInterval;
25
- }
26
24
  eventMap = new Map();
27
25
  writeQueue;
28
26
  indexCache;
@@ -36,19 +34,27 @@ export class RelayCore {
36
34
  this.indexCache = new IndexCache();
37
35
  this.indexCache.max = this.options.cacheIndexes;
38
36
  }
37
+ async flush() {
38
+ await this.writeQueue.flush();
39
+ // start next
40
+ this.writeTimeout = self.setTimeout(this.flush.bind(this), this.options.writeInterval);
41
+ }
39
42
  async start() {
43
+ if (this.running)
44
+ return;
40
45
  log("Starting");
41
- this.writeInterval = self.setInterval(() => {
42
- this.writeQueue.flush(this.options.batchWrite);
43
- }, this.options.writeInterval);
46
+ this.running = true;
47
+ await this.flush();
44
48
  this.pruneInterval = self.setInterval(() => {
45
49
  pruneLastUsed(this.db, this.options.maxEvents);
46
50
  }, this.options.pruneInterval);
47
51
  }
48
52
  async stop() {
49
- if (this.writeInterval) {
50
- self.clearInterval(this.writeInterval);
51
- this.writeInterval = undefined;
53
+ if (!this.running)
54
+ return;
55
+ if (this.writeTimeout) {
56
+ self.clearTimeout(this.writeTimeout);
57
+ this.writeTimeout = undefined;
52
58
  }
53
59
  if (this.pruneInterval) {
54
60
  self.clearInterval(this.pruneInterval);
@@ -1,5 +1,5 @@
1
- import require$$0$1 from 'tty';
2
- import require$$1 from 'util';
1
+ import require$$1 from 'tty';
2
+ import require$$1$1 from 'util';
3
3
  import require$$0 from 'os';
4
4
 
5
5
  const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
@@ -4324,8 +4324,8 @@ function getEventHash(event) {
4324
4324
  return bytesToHex(eventHash);
4325
4325
  }
4326
4326
  var i = new JS();
4327
- i.generateSecretKey;
4328
- i.getPublicKey;
4327
+ var generateSecretKey = i.generateSecretKey;
4328
+ var getPublicKey = i.getPublicKey;
4329
4329
  var finalizeEvent = i.finalizeEvent;
4330
4330
  var verifyEvent = i.verifyEvent;
4331
4331
 
@@ -4355,17 +4355,18 @@ __export(kinds_exports, {
4355
4355
  CreateOrUpdateStall: () => CreateOrUpdateStall,
4356
4356
  Curationsets: () => Curationsets,
4357
4357
  Date: () => Date2,
4358
+ DirectMessageRelaysList: () => DirectMessageRelaysList,
4358
4359
  DraftClassifiedListing: () => DraftClassifiedListing,
4359
4360
  DraftLong: () => DraftLong,
4360
4361
  Emojisets: () => Emojisets,
4361
4362
  EncryptedDirectMessage: () => EncryptedDirectMessage,
4362
- EncryptedDirectMessages: () => EncryptedDirectMessages,
4363
4363
  EventDeletion: () => EventDeletion,
4364
4364
  FileMetadata: () => FileMetadata,
4365
4365
  FileServerPreference: () => FileServerPreference,
4366
4366
  Followsets: () => Followsets,
4367
4367
  GenericRepost: () => GenericRepost,
4368
4368
  Genericlists: () => Genericlists,
4369
+ GiftWrap: () => GiftWrap,
4369
4370
  HTTPAuth: () => HTTPAuth,
4370
4371
  Handlerinformation: () => Handlerinformation,
4371
4372
  Handlerrecommendation: () => Handlerrecommendation,
@@ -4388,6 +4389,7 @@ __export(kinds_exports, {
4388
4389
  NostrConnect: () => NostrConnect,
4389
4390
  OpenTimestamps: () => OpenTimestamps,
4390
4391
  Pinlist: () => Pinlist,
4392
+ PrivateDirectMessage: () => PrivateDirectMessage,
4391
4393
  ProblemTracker: () => ProblemTracker,
4392
4394
  ProfileBadges: () => ProfileBadges,
4393
4395
  PublicChatsList: () => PublicChatsList,
@@ -4398,6 +4400,7 @@ __export(kinds_exports, {
4398
4400
  Report: () => Report,
4399
4401
  Reporting: () => Reporting,
4400
4402
  Repost: () => Repost,
4403
+ Seal: () => Seal,
4401
4404
  SearchRelaysList: () => SearchRelaysList,
4402
4405
  ShortTextNote: () => ShortTextNote,
4403
4406
  Time: () => Time,
@@ -4440,11 +4443,12 @@ var ShortTextNote = 1;
4440
4443
  var RecommendRelay = 2;
4441
4444
  var Contacts = 3;
4442
4445
  var EncryptedDirectMessage = 4;
4443
- var EncryptedDirectMessages = 4;
4444
4446
  var EventDeletion = 5;
4445
4447
  var Repost = 6;
4446
4448
  var Reaction = 7;
4447
4449
  var BadgeAward = 8;
4450
+ var Seal = 13;
4451
+ var PrivateDirectMessage = 14;
4448
4452
  var GenericRepost = 16;
4449
4453
  var ChannelCreation = 40;
4450
4454
  var ChannelMetadata = 41;
@@ -4452,6 +4456,7 @@ var ChannelMessage = 42;
4452
4456
  var ChannelHideMessage = 43;
4453
4457
  var ChannelMuteUser = 44;
4454
4458
  var OpenTimestamps = 1040;
4459
+ var GiftWrap = 1059;
4455
4460
  var FileMetadata = 1063;
4456
4461
  var LiveChatMessage = 1311;
4457
4462
  var ProblemTracker = 1971;
@@ -4476,6 +4481,7 @@ var BlockedRelaysList = 10006;
4476
4481
  var SearchRelaysList = 10007;
4477
4482
  var InterestsList = 10015;
4478
4483
  var UserEmojiList = 10030;
4484
+ var DirectMessageRelaysList = 10050;
4479
4485
  var FileServerPreference = 10096;
4480
4486
  var NWCWalletInfo = 13194;
4481
4487
  var LightningPubRPC = 21e3;
@@ -4627,6 +4633,7 @@ var nip19_exports = {};
4627
4633
  __export(nip19_exports, {
4628
4634
  BECH32_REGEX: () => BECH32_REGEX,
4629
4635
  Bech32MaxSize: () => Bech32MaxSize,
4636
+ NostrTypeGuard: () => NostrTypeGuard,
4630
4637
  decode: () => decode,
4631
4638
  encodeBytes: () => encodeBytes,
4632
4639
  naddrEncode: () => naddrEncode,
@@ -4634,9 +4641,18 @@ __export(nip19_exports, {
4634
4641
  noteEncode: () => noteEncode,
4635
4642
  nprofileEncode: () => nprofileEncode,
4636
4643
  npubEncode: () => npubEncode,
4637
- nrelayEncode: () => nrelayEncode,
4638
4644
  nsecEncode: () => nsecEncode
4639
4645
  });
4646
+ var NostrTypeGuard = {
4647
+ isNProfile: (value) => /^nprofile1[a-z\d]+$/.test(value || ""),
4648
+ isNRelay: (value) => /^nrelay1[a-z\d]+$/.test(value || ""),
4649
+ isNEvent: (value) => /^nevent1[a-z\d]+$/.test(value || ""),
4650
+ isNAddr: (value) => /^naddr1[a-z\d]+$/.test(value || ""),
4651
+ isNSec: (value) => /^nsec1[a-z\d]{58}$/.test(value || ""),
4652
+ isNPub: (value) => /^npub1[a-z\d]{58}$/.test(value || ""),
4653
+ isNote: (value) => /^note1[a-z\d]+$/.test(value || ""),
4654
+ isNcryptsec: (value) => /^ncryptsec1[a-z\d]+$/.test(value || "")
4655
+ };
4640
4656
  var Bech32MaxSize = 5e3;
4641
4657
  var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;
4642
4658
  function integerToUint8Array(number) {
@@ -4707,15 +4723,6 @@ function decode(nip19) {
4707
4723
  }
4708
4724
  };
4709
4725
  }
4710
- case "nrelay": {
4711
- let tlv = parseTLV(data);
4712
- if (!tlv[0]?.[0])
4713
- throw new Error("missing TLV 0 for nrelay");
4714
- return {
4715
- type: "nrelay",
4716
- data: utf8Decoder.decode(tlv[0][0])
4717
- };
4718
- }
4719
4726
  case "nsec":
4720
4727
  return { type: prefix, data };
4721
4728
  case "npub":
@@ -4787,12 +4794,6 @@ function naddrEncode(addr) {
4787
4794
  });
4788
4795
  return encodeBech32("naddr", data);
4789
4796
  }
4790
- function nrelayEncode(url) {
4791
- let data = encodeTLV({
4792
- 0: [utf8Encoder.encode(url)]
4793
- });
4794
- return encodeBech32("nrelay", data);
4795
- }
4796
4797
  function encodeTLV(tlv) {
4797
4798
  let entries = [];
4798
4799
  Object.entries(tlv).reverse().forEach(([t, vs]) => {
@@ -4842,12 +4843,14 @@ function getNormalizedX(key) {
4842
4843
  var nip05_exports = {};
4843
4844
  __export(nip05_exports, {
4844
4845
  NIP05_REGEX: () => NIP05_REGEX,
4846
+ isNip05: () => isNip05,
4845
4847
  isValid: () => isValid,
4846
4848
  queryProfile: () => queryProfile,
4847
4849
  searchDomain: () => searchDomain,
4848
4850
  useFetchImplementation: () => useFetchImplementation
4849
4851
  });
4850
4852
  var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/;
4853
+ var isNip05 = (value) => NIP05_REGEX.test(value || "");
4851
4854
  var _fetch;
4852
4855
  try {
4853
4856
  _fetch = fetch;
@@ -4988,10 +4991,10 @@ function minePow(unsigned, difficulty) {
4988
4991
  const tag = ["nonce", count.toString(), difficulty.toString()];
4989
4992
  event.tags.push(tag);
4990
4993
  while (true) {
4991
- const now = Math.floor(new Date().getTime() / 1e3);
4992
- if (now !== event.created_at) {
4994
+ const now2 = Math.floor(new Date().getTime() / 1e3);
4995
+ if (now2 !== event.created_at) {
4993
4996
  count = 0;
4994
- event.created_at = now;
4997
+ event.created_at = now2;
4995
4998
  }
4996
4999
  tag[1] = (++count).toString();
4997
5000
  event.id = getEventHash(event);
@@ -5575,6 +5578,65 @@ function makeZapReceipt({
5575
5578
  return zap;
5576
5579
  }
5577
5580
 
5581
+ // nip59.ts
5582
+ var nip59_exports = {};
5583
+ __export(nip59_exports, {
5584
+ createRumor: () => createRumor,
5585
+ createSeal: () => createSeal,
5586
+ createWrap: () => createWrap,
5587
+ unwrapEvent: () => unwrapEvent,
5588
+ wrapEvent: () => wrapEvent
5589
+ });
5590
+ var TWO_DAYS = 2 * 24 * 60 * 60;
5591
+ var now = () => Math.round(Date.now() / 1e3);
5592
+ var randomNow = () => Math.round(now() - Math.random() * TWO_DAYS);
5593
+ var nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey);
5594
+ var nip44Encrypt = (data, privateKey, publicKey) => encrypt2(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey));
5595
+ var nip44Decrypt = (data, privateKey) => JSON.parse(decrypt2(data.content, nip44ConversationKey(privateKey, data.pubkey)));
5596
+ function createRumor(event, privateKey) {
5597
+ const rumor = {
5598
+ created_at: now(),
5599
+ content: "",
5600
+ tags: [],
5601
+ ...event,
5602
+ pubkey: getPublicKey(privateKey)
5603
+ };
5604
+ rumor.id = getEventHash(rumor);
5605
+ return rumor;
5606
+ }
5607
+ function createSeal(rumor, privateKey, recipientPublicKey) {
5608
+ return finalizeEvent(
5609
+ {
5610
+ kind: Seal,
5611
+ content: nip44Encrypt(rumor, privateKey, recipientPublicKey),
5612
+ created_at: randomNow(),
5613
+ tags: []
5614
+ },
5615
+ privateKey
5616
+ );
5617
+ }
5618
+ function createWrap(seal, recipientPublicKey) {
5619
+ const randomKey = generateSecretKey();
5620
+ return finalizeEvent(
5621
+ {
5622
+ kind: GiftWrap,
5623
+ content: nip44Encrypt(seal, randomKey, recipientPublicKey),
5624
+ created_at: randomNow(),
5625
+ tags: [["p", recipientPublicKey]]
5626
+ },
5627
+ randomKey
5628
+ );
5629
+ }
5630
+ function wrapEvent(event, senderPrivateKey, recipientPublicKey) {
5631
+ const rumor = createRumor(event, senderPrivateKey);
5632
+ const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey);
5633
+ return createWrap(seal, recipientPublicKey);
5634
+ }
5635
+ function unwrapEvent(wrap, recipientPrivateKey) {
5636
+ const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey);
5637
+ return nip44Decrypt(unwrappedSeal, recipientPrivateKey);
5638
+ }
5639
+
5578
5640
  // nip98.ts
5579
5641
  var nip98_exports = {};
5580
5642
  __export(nip98_exports, {
@@ -5795,7 +5857,7 @@ function requireMs () {
5795
5857
  * @api public
5796
5858
  */
5797
5859
 
5798
- ms = function(val, options) {
5860
+ ms = function (val, options) {
5799
5861
  options = options || {};
5800
5862
  var type = typeof val;
5801
5863
  if (type === 'string' && val.length > 0) {
@@ -6506,12 +6568,12 @@ var hasRequiredHasFlag;
6506
6568
  function requireHasFlag () {
6507
6569
  if (hasRequiredHasFlag) return hasFlag;
6508
6570
  hasRequiredHasFlag = 1;
6509
- hasFlag = (flag, argv) => {
6510
- argv = argv || process.argv;
6571
+
6572
+ hasFlag = (flag, argv = process.argv) => {
6511
6573
  const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
6512
- const pos = argv.indexOf(prefix + flag);
6513
- const terminatorPos = argv.indexOf('--');
6514
- return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
6574
+ const position = argv.indexOf(prefix + flag);
6575
+ const terminatorPosition = argv.indexOf('--');
6576
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
6515
6577
  };
6516
6578
  return hasFlag;
6517
6579
  }
@@ -6523,23 +6585,32 @@ function requireSupportsColor () {
6523
6585
  if (hasRequiredSupportsColor) return supportsColor_1;
6524
6586
  hasRequiredSupportsColor = 1;
6525
6587
  const os = require$$0;
6588
+ const tty = require$$1;
6526
6589
  const hasFlag = requireHasFlag();
6527
6590
 
6528
- const env = process.env;
6591
+ const {env} = process;
6529
6592
 
6530
6593
  let forceColor;
6531
6594
  if (hasFlag('no-color') ||
6532
6595
  hasFlag('no-colors') ||
6533
- hasFlag('color=false')) {
6534
- forceColor = false;
6596
+ hasFlag('color=false') ||
6597
+ hasFlag('color=never')) {
6598
+ forceColor = 0;
6535
6599
  } else if (hasFlag('color') ||
6536
6600
  hasFlag('colors') ||
6537
6601
  hasFlag('color=true') ||
6538
6602
  hasFlag('color=always')) {
6539
- forceColor = true;
6603
+ forceColor = 1;
6540
6604
  }
6605
+
6541
6606
  if ('FORCE_COLOR' in env) {
6542
- forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
6607
+ if (env.FORCE_COLOR === 'true') {
6608
+ forceColor = 1;
6609
+ } else if (env.FORCE_COLOR === 'false') {
6610
+ forceColor = 0;
6611
+ } else {
6612
+ forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
6613
+ }
6543
6614
  }
6544
6615
 
6545
6616
  function translateLevel(level) {
@@ -6555,8 +6626,8 @@ function requireSupportsColor () {
6555
6626
  };
6556
6627
  }
6557
6628
 
6558
- function supportsColor(stream) {
6559
- if (forceColor === false) {
6629
+ function supportsColor(haveStream, streamIsTTY) {
6630
+ if (forceColor === 0) {
6560
6631
  return 0;
6561
6632
  }
6562
6633
 
@@ -6570,22 +6641,21 @@ function requireSupportsColor () {
6570
6641
  return 2;
6571
6642
  }
6572
6643
 
6573
- if (stream && !stream.isTTY && forceColor !== true) {
6644
+ if (haveStream && !streamIsTTY && forceColor === undefined) {
6574
6645
  return 0;
6575
6646
  }
6576
6647
 
6577
- const min = forceColor ? 1 : 0;
6648
+ const min = forceColor || 0;
6649
+
6650
+ if (env.TERM === 'dumb') {
6651
+ return min;
6652
+ }
6578
6653
 
6579
6654
  if (process.platform === 'win32') {
6580
- // Node.js 7.5.0 is the first version of Node.js to include a patch to
6581
- // libuv that enables 256 color output on Windows. Anything earlier and it
6582
- // won't work. However, here we target Node.js 8 at minimum as it is an LTS
6583
- // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
6584
- // release that supports 256 colors. Windows 10 build 14931 is the first release
6585
- // that supports 16m/TrueColor.
6655
+ // Windows 10 build 10586 is the first Windows release that supports 256 colors.
6656
+ // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
6586
6657
  const osRelease = os.release().split('.');
6587
6658
  if (
6588
- Number(process.versions.node.split('.')[0]) >= 8 &&
6589
6659
  Number(osRelease[0]) >= 10 &&
6590
6660
  Number(osRelease[2]) >= 10586
6591
6661
  ) {
@@ -6596,7 +6666,7 @@ function requireSupportsColor () {
6596
6666
  }
6597
6667
 
6598
6668
  if ('CI' in env) {
6599
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
6669
+ if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
6600
6670
  return 1;
6601
6671
  }
6602
6672
 
@@ -6635,22 +6705,18 @@ function requireSupportsColor () {
6635
6705
  return 1;
6636
6706
  }
6637
6707
 
6638
- if (env.TERM === 'dumb') {
6639
- return min;
6640
- }
6641
-
6642
6708
  return min;
6643
6709
  }
6644
6710
 
6645
6711
  function getSupportLevel(stream) {
6646
- const level = supportsColor(stream);
6712
+ const level = supportsColor(stream, stream && stream.isTTY);
6647
6713
  return translateLevel(level);
6648
6714
  }
6649
6715
 
6650
6716
  supportsColor_1 = {
6651
6717
  supportsColor: getSupportLevel,
6652
- stdout: getSupportLevel(process.stdout),
6653
- stderr: getSupportLevel(process.stderr)
6718
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
6719
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
6654
6720
  };
6655
6721
  return supportsColor_1;
6656
6722
  }
@@ -6665,8 +6731,8 @@ function requireNode () {
6665
6731
  if (hasRequiredNode) return node.exports;
6666
6732
  hasRequiredNode = 1;
6667
6733
  (function (module, exports) {
6668
- const tty = require$$0$1;
6669
- const util = require$$1;
6734
+ const tty = require$$1;
6735
+ const util = require$$1$1;
6670
6736
 
6671
6737
  /**
6672
6738
  * This is the Node.js implementation of `debug()`.
@@ -6950,6 +7016,8 @@ class WriteQueue {
6950
7016
  queuedIds = new Set();
6951
7017
  eventQueue = [];
6952
7018
  lastUsedQueue = new Set();
7019
+ /** Called for each chunk of events before they are written to the database */
7020
+ processEvents = null;
6953
7021
  constructor(db) {
6954
7022
  this.db = db;
6955
7023
  }
@@ -6979,7 +7047,7 @@ class WriteQueue {
6979
7047
  }
6980
7048
  async flush(count = 1000) {
6981
7049
  if (this.eventQueue.length > 0) {
6982
- const events = [];
7050
+ let events = [];
6983
7051
  for (let i = 0; i < count; i++) {
6984
7052
  const event = this.eventQueue.shift();
6985
7053
  if (!event)
@@ -6987,6 +7055,9 @@ class WriteQueue {
6987
7055
  events.push(event);
6988
7056
  this.queuedIds.delete(event.id);
6989
7057
  }
7058
+ if (this.processEvents) {
7059
+ events = (await this.processEvents(events)) || events;
7060
+ }
6990
7061
  await addEvents(this.db, events);
6991
7062
  log$4(`Wrote ${events.length} to database`);
6992
7063
  if (this.eventQueue.length > 0)
@@ -7376,11 +7447,9 @@ const log$1 = logger.extend("relay");
7376
7447
  /** Main class that implements the relay logic */
7377
7448
  class RelayCore {
7378
7449
  options;
7379
- writeInterval;
7450
+ running = false;
7451
+ writeTimeout;
7380
7452
  pruneInterval;
7381
- get running() {
7382
- return !!this.writeInterval;
7383
- }
7384
7453
  eventMap = new Map();
7385
7454
  writeQueue;
7386
7455
  indexCache;
@@ -7394,19 +7463,27 @@ class RelayCore {
7394
7463
  this.indexCache = new IndexCache();
7395
7464
  this.indexCache.max = this.options.cacheIndexes;
7396
7465
  }
7466
+ async flush() {
7467
+ await this.writeQueue.flush();
7468
+ // start next
7469
+ this.writeTimeout = self.setTimeout(this.flush.bind(this), this.options.writeInterval);
7470
+ }
7397
7471
  async start() {
7472
+ if (this.running)
7473
+ return;
7398
7474
  log$1("Starting");
7399
- this.writeInterval = self.setInterval(() => {
7400
- this.writeQueue.flush(this.options.batchWrite);
7401
- }, this.options.writeInterval);
7475
+ this.running = true;
7476
+ await this.flush();
7402
7477
  this.pruneInterval = self.setInterval(() => {
7403
7478
  pruneLastUsed(this.db, this.options.maxEvents);
7404
7479
  }, this.options.pruneInterval);
7405
7480
  }
7406
7481
  async stop() {
7407
- if (this.writeInterval) {
7408
- self.clearInterval(this.writeInterval);
7409
- this.writeInterval = undefined;
7482
+ if (!this.running)
7483
+ return;
7484
+ if (this.writeTimeout) {
7485
+ self.clearTimeout(this.writeTimeout);
7486
+ this.writeTimeout = undefined;
7410
7487
  }
7411
7488
  if (this.pruneInterval) {
7412
7489
  self.clearInterval(this.pruneInterval);
@@ -1,5 +1,5 @@
1
- import require$$0$1 from 'tty';
2
- import require$$1 from 'util';
1
+ import require$$1 from 'tty';
2
+ import require$$1$1 from 'util';
3
3
  import require$$0 from 'os';
4
4
 
5
5
  const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
@@ -355,7 +355,7 @@ function requireMs () {
355
355
  * @api public
356
356
  */
357
357
 
358
- ms = function(val, options) {
358
+ ms = function (val, options) {
359
359
  options = options || {};
360
360
  var type = typeof val;
361
361
  if (type === 'string' && val.length > 0) {
@@ -1066,12 +1066,12 @@ var hasRequiredHasFlag;
1066
1066
  function requireHasFlag () {
1067
1067
  if (hasRequiredHasFlag) return hasFlag;
1068
1068
  hasRequiredHasFlag = 1;
1069
- hasFlag = (flag, argv) => {
1070
- argv = argv || process.argv;
1069
+
1070
+ hasFlag = (flag, argv = process.argv) => {
1071
1071
  const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
1072
- const pos = argv.indexOf(prefix + flag);
1073
- const terminatorPos = argv.indexOf('--');
1074
- return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
1072
+ const position = argv.indexOf(prefix + flag);
1073
+ const terminatorPosition = argv.indexOf('--');
1074
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
1075
1075
  };
1076
1076
  return hasFlag;
1077
1077
  }
@@ -1083,23 +1083,32 @@ function requireSupportsColor () {
1083
1083
  if (hasRequiredSupportsColor) return supportsColor_1;
1084
1084
  hasRequiredSupportsColor = 1;
1085
1085
  const os = require$$0;
1086
+ const tty = require$$1;
1086
1087
  const hasFlag = requireHasFlag();
1087
1088
 
1088
- const env = process.env;
1089
+ const {env} = process;
1089
1090
 
1090
1091
  let forceColor;
1091
1092
  if (hasFlag('no-color') ||
1092
1093
  hasFlag('no-colors') ||
1093
- hasFlag('color=false')) {
1094
- forceColor = false;
1094
+ hasFlag('color=false') ||
1095
+ hasFlag('color=never')) {
1096
+ forceColor = 0;
1095
1097
  } else if (hasFlag('color') ||
1096
1098
  hasFlag('colors') ||
1097
1099
  hasFlag('color=true') ||
1098
1100
  hasFlag('color=always')) {
1099
- forceColor = true;
1101
+ forceColor = 1;
1100
1102
  }
1103
+
1101
1104
  if ('FORCE_COLOR' in env) {
1102
- forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
1105
+ if (env.FORCE_COLOR === 'true') {
1106
+ forceColor = 1;
1107
+ } else if (env.FORCE_COLOR === 'false') {
1108
+ forceColor = 0;
1109
+ } else {
1110
+ forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
1111
+ }
1103
1112
  }
1104
1113
 
1105
1114
  function translateLevel(level) {
@@ -1115,8 +1124,8 @@ function requireSupportsColor () {
1115
1124
  };
1116
1125
  }
1117
1126
 
1118
- function supportsColor(stream) {
1119
- if (forceColor === false) {
1127
+ function supportsColor(haveStream, streamIsTTY) {
1128
+ if (forceColor === 0) {
1120
1129
  return 0;
1121
1130
  }
1122
1131
 
@@ -1130,22 +1139,21 @@ function requireSupportsColor () {
1130
1139
  return 2;
1131
1140
  }
1132
1141
 
1133
- if (stream && !stream.isTTY && forceColor !== true) {
1142
+ if (haveStream && !streamIsTTY && forceColor === undefined) {
1134
1143
  return 0;
1135
1144
  }
1136
1145
 
1137
- const min = forceColor ? 1 : 0;
1146
+ const min = forceColor || 0;
1147
+
1148
+ if (env.TERM === 'dumb') {
1149
+ return min;
1150
+ }
1138
1151
 
1139
1152
  if (process.platform === 'win32') {
1140
- // Node.js 7.5.0 is the first version of Node.js to include a patch to
1141
- // libuv that enables 256 color output on Windows. Anything earlier and it
1142
- // won't work. However, here we target Node.js 8 at minimum as it is an LTS
1143
- // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
1144
- // release that supports 256 colors. Windows 10 build 14931 is the first release
1145
- // that supports 16m/TrueColor.
1153
+ // Windows 10 build 10586 is the first Windows release that supports 256 colors.
1154
+ // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
1146
1155
  const osRelease = os.release().split('.');
1147
1156
  if (
1148
- Number(process.versions.node.split('.')[0]) >= 8 &&
1149
1157
  Number(osRelease[0]) >= 10 &&
1150
1158
  Number(osRelease[2]) >= 10586
1151
1159
  ) {
@@ -1156,7 +1164,7 @@ function requireSupportsColor () {
1156
1164
  }
1157
1165
 
1158
1166
  if ('CI' in env) {
1159
- if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
1167
+ if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
1160
1168
  return 1;
1161
1169
  }
1162
1170
 
@@ -1195,22 +1203,18 @@ function requireSupportsColor () {
1195
1203
  return 1;
1196
1204
  }
1197
1205
 
1198
- if (env.TERM === 'dumb') {
1199
- return min;
1200
- }
1201
-
1202
1206
  return min;
1203
1207
  }
1204
1208
 
1205
1209
  function getSupportLevel(stream) {
1206
- const level = supportsColor(stream);
1210
+ const level = supportsColor(stream, stream && stream.isTTY);
1207
1211
  return translateLevel(level);
1208
1212
  }
1209
1213
 
1210
1214
  supportsColor_1 = {
1211
1215
  supportsColor: getSupportLevel,
1212
- stdout: getSupportLevel(process.stdout),
1213
- stderr: getSupportLevel(process.stderr)
1216
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
1217
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
1214
1218
  };
1215
1219
  return supportsColor_1;
1216
1220
  }
@@ -1225,8 +1229,8 @@ function requireNode () {
1225
1229
  if (hasRequiredNode) return node.exports;
1226
1230
  hasRequiredNode = 1;
1227
1231
  (function (module, exports) {
1228
- const tty = require$$0$1;
1229
- const util = require$$1;
1232
+ const tty = require$$1;
1233
+ const util = require$$1$1;
1230
1234
 
1231
1235
  /**
1232
1236
  * This is the Node.js implementation of `debug()`.
@@ -5512,8 +5516,8 @@ function getEventHash(event) {
5512
5516
  return bytesToHex(eventHash);
5513
5517
  }
5514
5518
  var i = new JS();
5515
- i.generateSecretKey;
5516
- i.getPublicKey;
5519
+ var generateSecretKey = i.generateSecretKey;
5520
+ var getPublicKey = i.getPublicKey;
5517
5521
  var finalizeEvent = i.finalizeEvent;
5518
5522
  var verifyEvent = i.verifyEvent;
5519
5523
 
@@ -5543,17 +5547,18 @@ __export(kinds_exports, {
5543
5547
  CreateOrUpdateStall: () => CreateOrUpdateStall,
5544
5548
  Curationsets: () => Curationsets,
5545
5549
  Date: () => Date2,
5550
+ DirectMessageRelaysList: () => DirectMessageRelaysList,
5546
5551
  DraftClassifiedListing: () => DraftClassifiedListing,
5547
5552
  DraftLong: () => DraftLong,
5548
5553
  Emojisets: () => Emojisets,
5549
5554
  EncryptedDirectMessage: () => EncryptedDirectMessage,
5550
- EncryptedDirectMessages: () => EncryptedDirectMessages,
5551
5555
  EventDeletion: () => EventDeletion,
5552
5556
  FileMetadata: () => FileMetadata,
5553
5557
  FileServerPreference: () => FileServerPreference,
5554
5558
  Followsets: () => Followsets,
5555
5559
  GenericRepost: () => GenericRepost,
5556
5560
  Genericlists: () => Genericlists,
5561
+ GiftWrap: () => GiftWrap,
5557
5562
  HTTPAuth: () => HTTPAuth,
5558
5563
  Handlerinformation: () => Handlerinformation,
5559
5564
  Handlerrecommendation: () => Handlerrecommendation,
@@ -5576,6 +5581,7 @@ __export(kinds_exports, {
5576
5581
  NostrConnect: () => NostrConnect,
5577
5582
  OpenTimestamps: () => OpenTimestamps,
5578
5583
  Pinlist: () => Pinlist,
5584
+ PrivateDirectMessage: () => PrivateDirectMessage,
5579
5585
  ProblemTracker: () => ProblemTracker,
5580
5586
  ProfileBadges: () => ProfileBadges,
5581
5587
  PublicChatsList: () => PublicChatsList,
@@ -5586,6 +5592,7 @@ __export(kinds_exports, {
5586
5592
  Report: () => Report,
5587
5593
  Reporting: () => Reporting,
5588
5594
  Repost: () => Repost,
5595
+ Seal: () => Seal,
5589
5596
  SearchRelaysList: () => SearchRelaysList,
5590
5597
  ShortTextNote: () => ShortTextNote,
5591
5598
  Time: () => Time,
@@ -5628,11 +5635,12 @@ var ShortTextNote = 1;
5628
5635
  var RecommendRelay = 2;
5629
5636
  var Contacts = 3;
5630
5637
  var EncryptedDirectMessage = 4;
5631
- var EncryptedDirectMessages = 4;
5632
5638
  var EventDeletion = 5;
5633
5639
  var Repost = 6;
5634
5640
  var Reaction = 7;
5635
5641
  var BadgeAward = 8;
5642
+ var Seal = 13;
5643
+ var PrivateDirectMessage = 14;
5636
5644
  var GenericRepost = 16;
5637
5645
  var ChannelCreation = 40;
5638
5646
  var ChannelMetadata = 41;
@@ -5640,6 +5648,7 @@ var ChannelMessage = 42;
5640
5648
  var ChannelHideMessage = 43;
5641
5649
  var ChannelMuteUser = 44;
5642
5650
  var OpenTimestamps = 1040;
5651
+ var GiftWrap = 1059;
5643
5652
  var FileMetadata = 1063;
5644
5653
  var LiveChatMessage = 1311;
5645
5654
  var ProblemTracker = 1971;
@@ -5664,6 +5673,7 @@ var BlockedRelaysList = 10006;
5664
5673
  var SearchRelaysList = 10007;
5665
5674
  var InterestsList = 10015;
5666
5675
  var UserEmojiList = 10030;
5676
+ var DirectMessageRelaysList = 10050;
5667
5677
  var FileServerPreference = 10096;
5668
5678
  var NWCWalletInfo = 13194;
5669
5679
  var LightningPubRPC = 21e3;
@@ -5815,6 +5825,7 @@ var nip19_exports = {};
5815
5825
  __export(nip19_exports, {
5816
5826
  BECH32_REGEX: () => BECH32_REGEX,
5817
5827
  Bech32MaxSize: () => Bech32MaxSize,
5828
+ NostrTypeGuard: () => NostrTypeGuard,
5818
5829
  decode: () => decode,
5819
5830
  encodeBytes: () => encodeBytes,
5820
5831
  naddrEncode: () => naddrEncode,
@@ -5822,9 +5833,18 @@ __export(nip19_exports, {
5822
5833
  noteEncode: () => noteEncode,
5823
5834
  nprofileEncode: () => nprofileEncode,
5824
5835
  npubEncode: () => npubEncode,
5825
- nrelayEncode: () => nrelayEncode,
5826
5836
  nsecEncode: () => nsecEncode
5827
5837
  });
5838
+ var NostrTypeGuard = {
5839
+ isNProfile: (value) => /^nprofile1[a-z\d]+$/.test(value || ""),
5840
+ isNRelay: (value) => /^nrelay1[a-z\d]+$/.test(value || ""),
5841
+ isNEvent: (value) => /^nevent1[a-z\d]+$/.test(value || ""),
5842
+ isNAddr: (value) => /^naddr1[a-z\d]+$/.test(value || ""),
5843
+ isNSec: (value) => /^nsec1[a-z\d]{58}$/.test(value || ""),
5844
+ isNPub: (value) => /^npub1[a-z\d]{58}$/.test(value || ""),
5845
+ isNote: (value) => /^note1[a-z\d]+$/.test(value || ""),
5846
+ isNcryptsec: (value) => /^ncryptsec1[a-z\d]+$/.test(value || "")
5847
+ };
5828
5848
  var Bech32MaxSize = 5e3;
5829
5849
  var BECH32_REGEX = /[\x21-\x7E]{1,83}1[023456789acdefghjklmnpqrstuvwxyz]{6,}/;
5830
5850
  function integerToUint8Array(number) {
@@ -5895,15 +5915,6 @@ function decode(nip19) {
5895
5915
  }
5896
5916
  };
5897
5917
  }
5898
- case "nrelay": {
5899
- let tlv = parseTLV(data);
5900
- if (!tlv[0]?.[0])
5901
- throw new Error("missing TLV 0 for nrelay");
5902
- return {
5903
- type: "nrelay",
5904
- data: utf8Decoder.decode(tlv[0][0])
5905
- };
5906
- }
5907
5918
  case "nsec":
5908
5919
  return { type: prefix, data };
5909
5920
  case "npub":
@@ -5975,12 +5986,6 @@ function naddrEncode(addr) {
5975
5986
  });
5976
5987
  return encodeBech32("naddr", data);
5977
5988
  }
5978
- function nrelayEncode(url) {
5979
- let data = encodeTLV({
5980
- 0: [utf8Encoder.encode(url)]
5981
- });
5982
- return encodeBech32("nrelay", data);
5983
- }
5984
5989
  function encodeTLV(tlv) {
5985
5990
  let entries = [];
5986
5991
  Object.entries(tlv).reverse().forEach(([t, vs]) => {
@@ -6030,12 +6035,14 @@ function getNormalizedX(key) {
6030
6035
  var nip05_exports = {};
6031
6036
  __export(nip05_exports, {
6032
6037
  NIP05_REGEX: () => NIP05_REGEX,
6038
+ isNip05: () => isNip05,
6033
6039
  isValid: () => isValid,
6034
6040
  queryProfile: () => queryProfile,
6035
6041
  searchDomain: () => searchDomain,
6036
6042
  useFetchImplementation: () => useFetchImplementation
6037
6043
  });
6038
6044
  var NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/;
6045
+ var isNip05 = (value) => NIP05_REGEX.test(value || "");
6039
6046
  var _fetch;
6040
6047
  try {
6041
6048
  _fetch = fetch;
@@ -6176,10 +6183,10 @@ function minePow(unsigned, difficulty) {
6176
6183
  const tag = ["nonce", count.toString(), difficulty.toString()];
6177
6184
  event.tags.push(tag);
6178
6185
  while (true) {
6179
- const now = Math.floor(new Date().getTime() / 1e3);
6180
- if (now !== event.created_at) {
6186
+ const now2 = Math.floor(new Date().getTime() / 1e3);
6187
+ if (now2 !== event.created_at) {
6181
6188
  count = 0;
6182
- event.created_at = now;
6189
+ event.created_at = now2;
6183
6190
  }
6184
6191
  tag[1] = (++count).toString();
6185
6192
  event.id = getEventHash(event);
@@ -6763,6 +6770,65 @@ function makeZapReceipt({
6763
6770
  return zap;
6764
6771
  }
6765
6772
 
6773
+ // nip59.ts
6774
+ var nip59_exports = {};
6775
+ __export(nip59_exports, {
6776
+ createRumor: () => createRumor,
6777
+ createSeal: () => createSeal,
6778
+ createWrap: () => createWrap,
6779
+ unwrapEvent: () => unwrapEvent,
6780
+ wrapEvent: () => wrapEvent
6781
+ });
6782
+ var TWO_DAYS = 2 * 24 * 60 * 60;
6783
+ var now = () => Math.round(Date.now() / 1e3);
6784
+ var randomNow = () => Math.round(now() - Math.random() * TWO_DAYS);
6785
+ var nip44ConversationKey = (privateKey, publicKey) => getConversationKey(privateKey, publicKey);
6786
+ var nip44Encrypt = (data, privateKey, publicKey) => encrypt2(JSON.stringify(data), nip44ConversationKey(privateKey, publicKey));
6787
+ var nip44Decrypt = (data, privateKey) => JSON.parse(decrypt2(data.content, nip44ConversationKey(privateKey, data.pubkey)));
6788
+ function createRumor(event, privateKey) {
6789
+ const rumor = {
6790
+ created_at: now(),
6791
+ content: "",
6792
+ tags: [],
6793
+ ...event,
6794
+ pubkey: getPublicKey(privateKey)
6795
+ };
6796
+ rumor.id = getEventHash(rumor);
6797
+ return rumor;
6798
+ }
6799
+ function createSeal(rumor, privateKey, recipientPublicKey) {
6800
+ return finalizeEvent(
6801
+ {
6802
+ kind: Seal,
6803
+ content: nip44Encrypt(rumor, privateKey, recipientPublicKey),
6804
+ created_at: randomNow(),
6805
+ tags: []
6806
+ },
6807
+ privateKey
6808
+ );
6809
+ }
6810
+ function createWrap(seal, recipientPublicKey) {
6811
+ const randomKey = generateSecretKey();
6812
+ return finalizeEvent(
6813
+ {
6814
+ kind: GiftWrap,
6815
+ content: nip44Encrypt(seal, randomKey, recipientPublicKey),
6816
+ created_at: randomNow(),
6817
+ tags: [["p", recipientPublicKey]]
6818
+ },
6819
+ randomKey
6820
+ );
6821
+ }
6822
+ function wrapEvent(event, senderPrivateKey, recipientPublicKey) {
6823
+ const rumor = createRumor(event, senderPrivateKey);
6824
+ const seal = createSeal(rumor, senderPrivateKey, recipientPublicKey);
6825
+ return createWrap(seal, recipientPublicKey);
6826
+ }
6827
+ function unwrapEvent(wrap, recipientPrivateKey) {
6828
+ const unwrappedSeal = nip44Decrypt(wrap, recipientPrivateKey);
6829
+ return nip44Decrypt(unwrappedSeal, recipientPrivateKey);
6830
+ }
6831
+
6766
6832
  // nip98.ts
6767
6833
  var nip98_exports = {};
6768
6834
  __export(nip98_exports, {
@@ -6950,6 +7016,8 @@ class WriteQueue {
6950
7016
  queuedIds = new Set();
6951
7017
  eventQueue = [];
6952
7018
  lastUsedQueue = new Set();
7019
+ /** Called for each chunk of events before they are written to the database */
7020
+ processEvents = null;
6953
7021
  constructor(db) {
6954
7022
  this.db = db;
6955
7023
  }
@@ -6979,7 +7047,7 @@ class WriteQueue {
6979
7047
  }
6980
7048
  async flush(count = 1000) {
6981
7049
  if (this.eventQueue.length > 0) {
6982
- const events = [];
7050
+ let events = [];
6983
7051
  for (let i = 0; i < count; i++) {
6984
7052
  const event = this.eventQueue.shift();
6985
7053
  if (!event)
@@ -6987,6 +7055,9 @@ class WriteQueue {
6987
7055
  events.push(event);
6988
7056
  this.queuedIds.delete(event.id);
6989
7057
  }
7058
+ if (this.processEvents) {
7059
+ events = (await this.processEvents(events)) || events;
7060
+ }
6990
7061
  await addEvents(this.db, events);
6991
7062
  log$4(`Wrote ${events.length} to database`);
6992
7063
  if (this.eventQueue.length > 0)
@@ -7376,11 +7447,9 @@ const log$1 = logger.extend("relay");
7376
7447
  /** Main class that implements the relay logic */
7377
7448
  class RelayCore {
7378
7449
  options;
7379
- writeInterval;
7450
+ running = false;
7451
+ writeTimeout;
7380
7452
  pruneInterval;
7381
- get running() {
7382
- return !!this.writeInterval;
7383
- }
7384
7453
  eventMap = new Map();
7385
7454
  writeQueue;
7386
7455
  indexCache;
@@ -7394,19 +7463,27 @@ class RelayCore {
7394
7463
  this.indexCache = new IndexCache();
7395
7464
  this.indexCache.max = this.options.cacheIndexes;
7396
7465
  }
7466
+ async flush() {
7467
+ await this.writeQueue.flush();
7468
+ // start next
7469
+ this.writeTimeout = self.setTimeout(this.flush.bind(this), this.options.writeInterval);
7470
+ }
7397
7471
  async start() {
7472
+ if (this.running)
7473
+ return;
7398
7474
  log$1("Starting");
7399
- this.writeInterval = self.setInterval(() => {
7400
- this.writeQueue.flush(this.options.batchWrite);
7401
- }, this.options.writeInterval);
7475
+ this.running = true;
7476
+ await this.flush();
7402
7477
  this.pruneInterval = self.setInterval(() => {
7403
7478
  pruneLastUsed(this.db, this.options.maxEvents);
7404
7479
  }, this.options.pruneInterval);
7405
7480
  }
7406
7481
  async stop() {
7407
- if (this.writeInterval) {
7408
- self.clearInterval(this.writeInterval);
7409
- this.writeInterval = undefined;
7482
+ if (!this.running)
7483
+ return;
7484
+ if (this.writeTimeout) {
7485
+ self.clearTimeout(this.writeTimeout);
7486
+ this.writeTimeout = undefined;
7410
7487
  }
7411
7488
  if (this.pruneInterval) {
7412
7489
  self.clearInterval(this.pruneInterval);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nostr-idb",
3
- "version": "2.1.6",
3
+ "version": "2.2.0",
4
4
  "description": "A collection of helper methods for storing nostr events in IndexedDB",
5
5
  "author": "hzrd149",
6
6
  "license": "MIT",
@@ -37,14 +37,6 @@
37
37
  "types": "./dist/worker/index.d.ts"
38
38
  }
39
39
  },
40
- "scripts": {
41
- "dev": "vite serve",
42
- "prebuild": "rm -rf dist",
43
- "build": "tsc && rollup -c",
44
- "build:examples": "vite build && cp examples/index.html public/index.html",
45
- "prepare": "tsc && rollup -c",
46
- "format": "prettier -w ."
47
- },
48
40
  "dependencies": {
49
41
  "debug": "^4.3.6",
50
42
  "idb": "^8.0.0",
@@ -77,5 +69,12 @@
77
69
  "funding": {
78
70
  "type": "lightning",
79
71
  "url": "lightning:hzrd149@getalby.com"
72
+ },
73
+ "scripts": {
74
+ "dev": "vite serve",
75
+ "prebuild": "rm -rf dist",
76
+ "build": "tsc && rollup -c",
77
+ "build:examples": "vite build && cp examples/index.html public/index.html",
78
+ "format": "prettier -w ."
80
79
  }
81
- }
80
+ }
package/CHANGELOG.md DELETED
@@ -1,78 +0,0 @@
1
- # nostr-idb
2
-
3
- ## 2.1.6
4
-
5
- ### Patch Changes
6
-
7
- - Add error handler for onevent callback
8
-
9
- ## 2.1.5
10
-
11
- ### Patch Changes
12
-
13
- - Add timeout for subscriptions
14
-
15
- ## 2.1.4
16
-
17
- ### Patch Changes
18
-
19
- - Add missing fire method to subscription type
20
-
21
- ## 2.1.1
22
-
23
- ### Patch Changes
24
-
25
- - 890f64a: don't rebroadcast duplicate events
26
-
27
- ## 2.1.0
28
-
29
- ### Minor Changes
30
-
31
- - 55e853c: Add in memory eventMap to relay core
32
-
33
- ## 2.0.1
34
-
35
- ### Patch Changes
36
-
37
- - e4ec1d1: Fix multiple filters being interpreted as and
38
-
39
- ## 2.0.0
40
-
41
- ### Major Changes
42
-
43
- - d7c74fb: Remove single `addEvent` method
44
- - e09e98c: Add `WebSocket` class
45
- - e09e98c: Add `LocalWebSocket` class
46
- - e09e98c: Add `WorkerWebSocket` class
47
- - e09e98c: Add `SharedWorkerWebSocket` class
48
- - e09e98c: Add `NostrIDBWorker` and `NostrIDBSharedWorker` classes
49
-
50
- ## 1.1.1
51
-
52
- ### Patch Changes
53
-
54
- - ec4b4e2: Fix event UID
55
-
56
- ## 1.1.0
57
-
58
- ### Minor Changes
59
-
60
- - 7004c24: Add simple prune methods
61
-
62
- ## 1.0.0
63
-
64
- ### Major Changes
65
-
66
- - 9bbdbc7: Upgrade nostr-tools to v2
67
-
68
- ### Minor Changes
69
-
70
- - 9bbdbc7: Support ephemeral events
71
- - 446cb1e: Support replaceable and parameterized replaceable events
72
-
73
- ## 0.2.0
74
-
75
- ### Minor Changes
76
-
77
- - f223129: Added `CacheRelay` class
78
- - 6c04558: Add `IndexCache` for relay