@blocks-network/sdk 0.1.45

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 (74) hide show
  1. package/README.md +632 -0
  2. package/dist/cli/run.d.ts +39 -0
  3. package/dist/cli/run.js +2 -0
  4. package/dist/config-loader.d.ts +10 -0
  5. package/dist/config-loader.js +1 -0
  6. package/dist/defaults.d.ts +7 -0
  7. package/dist/defaults.js +1 -0
  8. package/dist/env.d.ts +5 -0
  9. package/dist/env.js +1 -0
  10. package/dist/index.d.ts +28 -0
  11. package/dist/index.js +1 -0
  12. package/dist/runtime/agent-auth.d.ts +94 -0
  13. package/dist/runtime/agent-auth.js +1 -0
  14. package/dist/runtime/agent-instance.d.ts +233 -0
  15. package/dist/runtime/agent-instance.js +1 -0
  16. package/dist/runtime/agent-registry.d.ts +270 -0
  17. package/dist/runtime/agent-registry.js +1 -0
  18. package/dist/runtime/artifacts.d.ts +65 -0
  19. package/dist/runtime/artifacts.js +1 -0
  20. package/dist/runtime/auth-provider.d.ts +39 -0
  21. package/dist/runtime/auth-provider.js +1 -0
  22. package/dist/runtime/cdm-config.d.ts +16 -0
  23. package/dist/runtime/cdm-config.js +1 -0
  24. package/dist/runtime/channel-manager.d.ts +125 -0
  25. package/dist/runtime/channel-manager.js +1 -0
  26. package/dist/runtime/consumer-auth.d.ts +112 -0
  27. package/dist/runtime/consumer-auth.js +1 -0
  28. package/dist/runtime/credential-cache.d.ts +40 -0
  29. package/dist/runtime/credential-cache.js +1 -0
  30. package/dist/runtime/file-input.d.ts +37 -0
  31. package/dist/runtime/file-input.js +1 -0
  32. package/dist/runtime/file-upload.d.ts +112 -0
  33. package/dist/runtime/file-upload.js +1 -0
  34. package/dist/runtime/part-helpers.d.ts +52 -0
  35. package/dist/runtime/part-helpers.js +1 -0
  36. package/dist/runtime/protocol-version.d.ts +18 -0
  37. package/dist/runtime/protocol-version.js +1 -0
  38. package/dist/runtime/pubnub-client.d.ts +8 -0
  39. package/dist/runtime/pubnub-client.js +1 -0
  40. package/dist/runtime/pubnub-types.d.ts +119 -0
  41. package/dist/runtime/pubnub-types.js +1 -0
  42. package/dist/runtime/rpc-client.d.ts +45 -0
  43. package/dist/runtime/rpc-client.js +1 -0
  44. package/dist/runtime/stream-context.d.ts +69 -0
  45. package/dist/runtime/stream-context.js +1 -0
  46. package/dist/runtime/stream-ref.d.ts +74 -0
  47. package/dist/runtime/stream-ref.js +1 -0
  48. package/dist/runtime/stream-registry.d.ts +133 -0
  49. package/dist/runtime/stream-registry.js +1 -0
  50. package/dist/runtime/stream-setup-helper.d.ts +87 -0
  51. package/dist/runtime/stream-setup-helper.js +1 -0
  52. package/dist/runtime/task-client.d.ts +259 -0
  53. package/dist/runtime/task-client.js +1 -0
  54. package/dist/runtime/task-session.d.ts +224 -0
  55. package/dist/runtime/task-session.js +1 -0
  56. package/dist/runtime/write-affinity.d.ts +22 -0
  57. package/dist/runtime/write-affinity.js +1 -0
  58. package/dist/runtime/write-affinity.test.d.ts +1 -0
  59. package/dist/runtime/write-affinity.test.js +1 -0
  60. package/dist/stream/bytes.d.ts +14 -0
  61. package/dist/stream/bytes.js +1 -0
  62. package/dist/stream/descriptor.d.ts +47 -0
  63. package/dist/stream/descriptor.js +1 -0
  64. package/dist/stream/index.d.ts +11 -0
  65. package/dist/stream/index.js +1 -0
  66. package/dist/stream/stream-bundle.d.ts +82 -0
  67. package/dist/stream/stream-bundle.js +1 -0
  68. package/dist/stream/stream-client.d.ts +192 -0
  69. package/dist/stream/stream-client.js +1 -0
  70. package/dist/stream/types.d.ts +75 -0
  71. package/dist/stream/types.js +1 -0
  72. package/dist/stream/validate.d.ts +15 -0
  73. package/dist/stream/validate.js +1 -0
  74. package/package.json +74 -0
@@ -0,0 +1 @@
1
+ import e from"pubnub";import{StreamBundle as t}from"./stream-bundle.js";import{validateStreamId as r}from"./validate.js";import{getEnv as i}from"../env.js";import{base64ToBytes as n,concatBytes as s,utf8Decode as o,utf8Encode as a}from"./bytes.js";let u=0;export function _resetUuidCounter(){u=0}function d(e,t,r,n){if(void 0!==e)return e;const s=i(t);return void 0!==s&&""!==s?n(s):r}function h(e){return Number(e)}function l(e){const t=e.toLowerCase();return"true"===t||"on"===t||"1"===t}export const FATAL_STREAM_ERROR_CATEGORIES=new Set(["PNAccessDeniedCategory","PNBadRequestCategory"]);export function isStreamStatusError(e){if(!e)return!1;if(e.error)return!0;const t=e.statusCode;if("number"==typeof t&&t>=400)return!0;const r="string"==typeof e.category?e.category:"";return""!==r&&FATAL_STREAM_ERROR_CATEGORIES.has(r)}export function isFatalStreamCategory(e){return"string"==typeof e&&FATAL_STREAM_ERROR_CATEGORIES.has(e)}export class StreamClient{constructor(i){this._isActive=!0,this.endCallbacks=[],this.inboundDoneCallbacks=[],this.inboundDoneFired=!1,this.errorCallbacks=[],this.inboundQueue=[],this.inboundResolve=null,this.inboundDone=!1,this.messageListener=null,this.multipartBuffers=new Map,this.reorderBuffer=new Map,this.reorderTimer=null,this.endSeq=null;const n=i.agentName;if(!n)throw new Error("agentName is required (pass in options)");if(r(i.streamId),this.format=i.format??"bytes","bytes"!==this.format&&"events"!==this.format)throw new Error(`Invalid stream format: "${this.format}". Must be "bytes" or "events".`);this.direction=i.direction??"outbound";const s=i.affinity;null==s?this._affinity="dedicated":"dedicated"===s||"shared"===s?this._affinity=s:(console.warn("[StreamClient] stream_client_invalid_affinity_fallback",{streamId:i.streamId,receivedAffinity:s,fallbackAffinity:"dedicated"}),this._affinity="dedicated"),this.nextExpectedSeq="events"===this.format?1:0,this.reorderTimeoutMs=i.reorderTimeoutMs??750,u++,this._uuid=`${n}-stream-${String(u).padStart(4,"0")}`,this._channel=i.channel??`stream.${n}.${i.streamId}`;const o=d(i.maxMessageSize,"STREAM_MAX_MESSAGE_SIZE",16384,h),a=d(i.bundleSizeBytes,"STREAM_BUNDLE_SIZE",4096,h),c=d(i.maxLatencyMs,"STREAM_MAX_LATENCY_MS",250,h),f=d(i.gating,"STREAM_GATING",!0,l);this.pubnub=new e({subscribeKey:i.subscribeKey,publishKey:i.publishKey,userId:this._uuid,enableEventEngine:!0}),this.pubnub.setToken(i.token),"bidirectional"===this.direction&&this.pubnub.setFilterExpression(`meta.sender != '${this._uuid}'`);if("outbound"===this.direction||"bidirectional"===this.direction){const e={maxMessageSize:o,bundleSizeBytes:a,maxLatencyMs:c,uuid:this._uuid};this.bundle=new t(this.pubnub,this._channel,i.streamId,this.format,e,f)}else this.bundle=null;("inbound"===this.direction||"bidirectional"===this.direction)&&this.setupInbound()}get isActive(){return this._isActive}get channel(){return this._channel}get uuid(){return this._uuid}write(e){if(!this._isActive)throw new Error("Cannot write to an ended stream");if(!this.bundle)throw new Error("Cannot write to an inbound-only stream");this.bundle.write(e)}async end(){if(this._isActive){if(this._isActive=!1,this.bundle)try{await this.bundle.end()}catch(e){console.warn("[StreamClient] bundle.end() failed during end() (continuing teardown):",e)}if("bidirectional"!==this.direction&&this.bundle&&"shared"!==this._affinity)try{await this.bundle.publishEndMarker()}catch(e){console.warn("[StreamClient] publishEndMarker() failed during end() (continuing teardown):",e)}this.inboundDone=!0,this.inboundResolve&&(this.inboundResolve({value:void 0,done:!0}),this.inboundResolve=null),this.fireInboundDone(),this.multipartBuffers.clear(),this.reorderBuffer.clear(),this.reorderTimer&&(clearTimeout(this.reorderTimer),this.reorderTimer=null),this.messageListener&&(this.pubnub.removeListener(this.messageListener),this.messageListener=null),this.pubnub.unsubscribeAll(),this.pubnub.destroy();for(const e of this.endCallbacks)e();this.endCallbacks=[]}}onEnd(e){this.endCallbacks.push(e)}onInboundDone(e){this.inboundDoneFired?e():this.inboundDoneCallbacks.push(e)}fireInboundDone(){if(!this.inboundDoneFired){this.inboundDoneFired=!0;for(const e of this.inboundDoneCallbacks)try{e()}catch{}this.inboundDoneCallbacks=[]}}onError(e){this.errorCallbacks.push(e)}fireError(e){for(const t of[...this.errorCallbacks])try{t(e)}catch(e){console.error("[StreamClient] onError callback raised:",e)}}get inbound(){if("outbound"===this.direction)throw new Error("Cannot read from an outbound-only stream");const e=this;return{[Symbol.asyncIterator]:()=>({next:()=>e.inboundQueue.length>0?Promise.resolve({value:e.inboundQueue.shift(),done:!1}):e.inboundDone?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{e.inboundResolve=t})})}}setupInbound(){this.messageListener={message:e=>{e.channel===this._channel&&this.handleInboundMessage(e.message)},status:e=>{this.handleStatusEvent(e)}},this.pubnub.addListener(this.messageListener),this.pubnub.subscribe({channels:[this._channel],timetoken:1e3})}handleStatusEvent(e){try{if(!isStreamStatusError(e))return;const t="string"==typeof e?.category?e.category:"",r=isFatalStreamCategory(t),i=e?.errorData??e?.error??null,n={category:t,error:i,channel:this._channel,timestamp:Date.now(),fatal:r};console.warn(`[StreamClient] status error: category=${t} fatal=${r} channel=${this._channel}`,i),this.fireError(n),r&&this._isActive&&this.end().catch(e=>{console.error("[StreamClient] forced end() after fatal error raised:",e)})}catch(e){console.error("[StreamClient] status handler raised:",e)}}handleInboundMessage(e){if(!e||"object"!=typeof e)return;const t=e;if("stream_end"===t.type)return this.reorderTimeoutMs<=0?(this.inboundDone=!0,this.inboundResolve&&(this.inboundResolve({value:void 0,done:!0}),this.inboundResolve=null),void this.fireInboundDone()):"number"==typeof t.seq&&Number.isInteger(t.seq)?(this.endSeq=t.seq,void(this.nextExpectedSeq>=this.endSeq?this.checkEndReached():this.startReorderTimer())):void console.warn("[StreamClient] stream_end missing numeric seq field; ignoring in reorder mode");if(t.multipart&&"object"==typeof t.multipart){const e=t.multipart;return void this.handleMultipartPart(t,e)}const r=this.normalizeMessage(t);r&&this.enqueueReordered(r)}handleMultipartPart(e,t){if(!function(e){return!("string"!=typeof e.id||""===e.id||"number"!=typeof e.part||!Number.isInteger(e.part)||e.part<1||"number"!=typeof e.total||!Number.isInteger(e.total)||e.total<2||e.part>e.total)}(t))return;if("string"!=typeof e.data)return;this.evictStaleGroups();const r=e.seq,i=e.type,a=e.streamId,u=e.data;let d=this.multipartBuffers.get(t.id);if(d){if(d.total!==t.total||d.seq!==r||d.type!==i||d.streamId!==a)return void this.dropMultipartGroup(t.id);const e=d.parts.get(t.part);if(void 0!==e){if(e===u)return;return void this.dropMultipartGroup(t.id)}}else d={total:t.total,parts:new Map,seq:r,ts:e.ts,type:i,streamId:a,createdAt:Date.now()},this.multipartBuffers.set(t.id,d);if(d.parts.set(t.part,u),d.parts.size===d.total){this.dropMultipartGroup(t.id);for(let e=1;e<=d.total;e++)if(!d.parts.has(e))return;try{const e=[];for(let t=1;t<=d.total;t++)e.push(n(d.parts.get(t)));const t=s(e),r=JSON.parse(o(t)),i=this.normalizeMessage(r);i&&this.enqueueReordered(i)}catch{}}}dropMultipartGroup(e){this.multipartBuffers.delete(e)}evictStaleGroups(){const e=Date.now();for(const[t,r]of this.multipartBuffers)e-r.createdAt>3e4&&this.multipartBuffers.delete(t);if(this.multipartBuffers.size>64){const e=[...this.multipartBuffers.entries()].sort((e,t)=>e[1].createdAt-t[1].createdAt),t=e.length-64;for(let r=0;r<t;r++)this.multipartBuffers.delete(e[r][0])}}normalizeMessage(e){const t=e.type;if("stream_data"===t){if("number"!=typeof e.seq||!Number.isInteger(e.seq))return null;const t=e.chunks;if(!Array.isArray(t)||0===t.length||!t.every(e=>"string"==typeof e))return null;const r=e.encoding;return void 0!==r&&"utf8"!==r&&"base64"!==r?null:{data:t,seq:e.seq,ts:e.ts,format:"bytes",encoding:r??"utf8"}}if("stream_events"===t){if("number"!=typeof e.seq||!Number.isInteger(e.seq))return null;const t=e.events;return Array.isArray(t)&&0!==t.length?{data:t,seq:e.seq,ts:e.ts,format:"events",encoding:"utf8"}:null}return"number"==typeof e.seq&&Number.isInteger(e.seq)?{data:e,seq:e.seq,ts:e.ts??Date.now(),format:"raw",encoding:"utf8"}:null}enqueueInbound(e){if(this.inboundResolve){const t=this.inboundResolve;this.inboundResolve=null,t({value:e,done:!1})}else this.inboundQueue.push(e)}enqueueReordered(e){if(this.reorderTimeoutMs<=0)return void this.enqueueInbound(e);const t=e.seq;null!==this.endSeq&&t>=this.endSeq||t<this.nextExpectedSeq||this.reorderBuffer.has(t)||(t===this.nextExpectedSeq?(this.enqueueInbound(e),this.nextExpectedSeq++,this.flushConsecutive(),this.cancelAndRestartTimerIfNeeded(),this.checkEndReached()):(this.reorderBuffer.set(t,e),this.startReorderTimer()))}flushConsecutive(){for(;this.reorderBuffer.has(this.nextExpectedSeq);){const e=this.reorderBuffer.get(this.nextExpectedSeq);this.reorderBuffer.delete(this.nextExpectedSeq),this.enqueueInbound(e),this.nextExpectedSeq++}}startReorderTimer(){this.reorderTimer||(this.reorderTimer=setTimeout(()=>{if(this.reorderTimer=null,this.reorderBuffer.size>0){let e=1/0;for(const t of this.reorderBuffer.keys())t<e&&(e=t);this.nextExpectedSeq=e,this.flushConsecutive(),this.cancelAndRestartTimerIfNeeded(),this.checkEndReached()}else null!==this.endSeq&&this.nextExpectedSeq<this.endSeq&&(this.nextExpectedSeq=this.endSeq,this.checkEndReached())},this.reorderTimeoutMs))}cancelAndRestartTimerIfNeeded(){this.reorderTimer&&(clearTimeout(this.reorderTimer),this.reorderTimer=null),this.reorderBuffer.size>0&&this.startReorderTimer()}checkEndReached(){null!==this.endSeq&&this.nextExpectedSeq>=this.endSeq&&(this.reorderBuffer.size>0&&(console.warn(`[StreamClient] reorder buffer not empty at stream end (${this.reorderBuffer.size} unexpected messages with seq >= ${this.endSeq})`),this.reorderBuffer.clear()),this.reorderTimer&&(clearTimeout(this.reorderTimer),this.reorderTimer=null),this.inboundDone=!0,this.inboundResolve&&(this.inboundResolve({value:void 0,done:!0}),this.inboundResolve=null),this.fireInboundDone())}async*bytes(){for await(const e of this.inbound){const t=Array.isArray(e.data)?e.data:[e.data];for(const r of t)yield"base64"===e.encoding?n(r):a(r)}}async*events(){for await(const e of this.inbound){const t=Array.isArray(e.data)?e.data:[e.data];for(const e of t)yield e}}async readable(){const{Readable:e}=await import("node:stream"),t=this.bytes()[Symbol.asyncIterator]();return new e({async read(){try{const{value:e,done:r}=await t.next();r?this.push(null):this.push(e)}catch{this.push(null)}}})}static fromDescriptor(e,t){const r=e.localDirection,i="outbound"===r||"bidirectional"===r,n=void 0!==t.gating?t.gating:!i;return new StreamClient({subscribeKey:t.subscribeKey,publishKey:t.publishKey,token:e.token,agentName:e.agentName,streamId:e.streamId,channel:e.channel,direction:e.localDirection,format:e.format,affinity:e.affinity,maxMessageSize:t.maxMessageSize,bundleSizeBytes:t.bundleSizeBytes,maxLatencyMs:t.maxLatencyMs,gating:n,reorderTimeoutMs:t.reorderTimeoutMs})}}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Shared types for the Stream SDK.
3
+ *
4
+ * These types define the public API surface for stream configuration,
5
+ * direction modes, and inbound message shape.
6
+ */
7
+ /** Wire format for stream data: 'bytes' for chunked text/binary, 'events' for structured objects. */
8
+ export type StreamFormat = 'bytes' | 'events';
9
+ /** Direction of stream data flow relative to the local client. */
10
+ export type StreamDirection = 'outbound' | 'inbound' | 'bidirectional';
11
+ /** Stream affinity — re-exported from descriptor.ts for call-site convenience. */
12
+ export type StreamAffinity = 'dedicated' | 'shared';
13
+ /** Configuration for StreamBundle (internal transport engine). */
14
+ export interface StreamBundleConfig {
15
+ /** Maximum serialized message size before multipart splitting. Default: 16384. */
16
+ maxMessageSize: number;
17
+ /** Flush buffer when accumulated byte size reaches this limit. Default: 4096. */
18
+ bundleSizeBytes: number;
19
+ /** Flush buffer after this many ms since first unflushed write. Default: 250. */
20
+ maxLatencyMs: number;
21
+ /** Publisher UUID for meta.sender on every publish. */
22
+ uuid: string;
23
+ }
24
+ /** Options for constructing a StreamClient directly. */
25
+ export interface StreamClientOptions {
26
+ subscribeKey: string;
27
+ publishKey: string;
28
+ /** Per-stream token (T7a from setup handshake). */
29
+ token: string;
30
+ /** Agent name. Required. */
31
+ agentName: string;
32
+ streamId: string;
33
+ /** Explicit channel name. Default: computed as stream.{agentName}.{streamId}. */
34
+ channel?: string;
35
+ /** Wire format. Default: 'bytes'. */
36
+ format?: StreamFormat;
37
+ /** Direction of data flow. Default: 'outbound'. */
38
+ direction?: StreamDirection;
39
+ /** Max serialized message size before multipart splitting. Default: 16384 (or STREAM_MAX_MESSAGE_SIZE). */
40
+ maxMessageSize?: number;
41
+ /** Flush buffer at this byte size. Default: 4096 (or STREAM_BUNDLE_SIZE). */
42
+ bundleSizeBytes?: number;
43
+ /** Flush buffer after this many ms. Default: 250 (or STREAM_MAX_LATENCY_MS). */
44
+ maxLatencyMs?: number;
45
+ /** Presence gating. Default: true (or STREAM_GATING). */
46
+ gating?: boolean;
47
+ /** Reorder buffer timeout in ms. Default: 750. Set to 0 to disable. */
48
+ reorderTimeoutMs?: number;
49
+ /**
50
+ * Stream affinity — gates the `stream_end` publish on shared channels.
51
+ * Shared streams never publish the end marker from either producer or
52
+ * consumer-writer paths (SDK_CONTRACT §8.4.1a shared-affinity carve-out).
53
+ * Default: 'dedicated'.
54
+ */
55
+ affinity?: StreamAffinity;
56
+ }
57
+ /** Options for StreamClient.fromDescriptor(). Keys not in the descriptor. */
58
+ export interface StreamClientFromDescriptorOptions {
59
+ subscribeKey: string;
60
+ publishKey: string;
61
+ maxMessageSize?: number;
62
+ bundleSizeBytes?: number;
63
+ maxLatencyMs?: number;
64
+ gating?: boolean;
65
+ /** Reorder buffer timeout in ms. Default: 750. Set to 0 to disable. */
66
+ reorderTimeoutMs?: number;
67
+ }
68
+ /** Normalized inbound message yielded by the inbound async iterator. */
69
+ export interface InboundMessage {
70
+ data: unknown;
71
+ seq: number;
72
+ ts: number;
73
+ format: 'bytes' | 'events' | 'raw';
74
+ encoding: string;
75
+ }
@@ -0,0 +1 @@
1
+ export{};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Stream ID validation.
3
+ *
4
+ * Stream IDs appear in the channel name: stream.{agentName}.{streamId}
5
+ * Dots are disallowed because they are PubNub channel hierarchy separators.
6
+ */
7
+ /**
8
+ * Validate a stream ID. Throws if the ID is invalid.
9
+ *
10
+ * Rules:
11
+ * - Cannot be empty
12
+ * - Cannot exceed 92 bytes
13
+ * - Only [a-zA-Z0-9-_] allowed (no dots)
14
+ */
15
+ export declare function validateStreamId(id: string): void;
@@ -0,0 +1 @@
1
+ import{utf8ByteLength as t}from"./bytes.js";const r=/^[a-zA-Z0-9\-_]+$/;export function validateStreamId(e){if(0===e.length)throw new Error("Stream ID cannot be empty");if(t(e)>92)throw new Error("Stream ID exceeds 92 byte limit");if(!r.test(e))throw new Error("Stream ID contains invalid characters. Allowed: a-z, A-Z, 0-9, -, _")}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@blocks-network/sdk",
3
+ "version": "0.1.45",
4
+ "type": "module",
5
+ "description": "Blocks Network SDK — build and run A2A agents on PubNub",
6
+ "exports": {
7
+ ".": {
8
+ "browser": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./stream": {
16
+ "browser": {
17
+ "types": "./dist/stream/index.d.ts",
18
+ "default": "./dist/stream/index.js"
19
+ },
20
+ "types": "./dist/stream/index.d.ts",
21
+ "default": "./dist/stream/index.js"
22
+ }
23
+ },
24
+ "bin": {
25
+ "blocks-run": "dist/cli/run.js"
26
+ },
27
+ "files": [
28
+ "dist/",
29
+ "schemas/",
30
+ "README.md"
31
+ ],
32
+ "engines": {
33
+ "node": ">=20.0.0"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "build:release": "tsc && npm run minify",
38
+ "minify": "find dist -name '*.js' -exec terser {} --module --compress --mangle --output {} \\;",
39
+ "lint": "eslint src/ tests/ --ext .ts",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest watch"
42
+ },
43
+ "dependencies": {
44
+ "dotenv": "^16.4.0",
45
+ "pubnub": "~10.2.3",
46
+ "tsx": "~4.21.0"
47
+ },
48
+ "devDependencies": {
49
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
50
+ "@typescript-eslint/parser": "^7.0.0",
51
+ "ajv": "^8.17.1",
52
+ "eslint": "^8.57.1",
53
+ "jsdom": "^29.0.2",
54
+ "terser": "^5.46.1",
55
+ "typescript": "^5.4.5",
56
+ "vite": "^5.4.21",
57
+ "vitest": "^1.6.0"
58
+ },
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/pubnub/blocksnetwork.git",
62
+ "directory": "blocks-sdk/sdks/node"
63
+ },
64
+ "homepage": "https://github.com/pubnub/blocksnetwork/tree/main/blocks-sdk/sdks/node#readme",
65
+ "bugs": {
66
+ "url": "https://github.com/pubnub/blocksnetwork/issues"
67
+ },
68
+ "license": "PubNub",
69
+ "overrides": {
70
+ "pubnub": {
71
+ "react-native-url-polyfill": "npm:empty-npm-package@1.0.0"
72
+ }
73
+ }
74
+ }