@pindownai/mastra-pindown 0.1.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/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +294 -0
- package/dist/index.d.ts +294 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Pindown.ai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# @mastra/pindown
|
|
2
|
+
|
|
3
|
+
Mastra workflow integration for Pindown.ai - Real-time workflow execution updates via HTTP PubSub.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@mastra/pindown` wraps your Mastra workflows and publishes execution events to Pindown.ai backend API. The backend validates your API key, counts requests, and writes events to Firebase for real-time frontend subscriptions.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
**Requirements:**
|
|
12
|
+
- Node.js 22.0.0 or higher
|
|
13
|
+
- Mastra 1.0.0 or higher
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @mastra/pindown
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### 1. Initialize
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { init } from '@mastra/pindown';
|
|
25
|
+
|
|
26
|
+
// Production (defaults to http://api.pindown.ai)
|
|
27
|
+
const { createWorkflow, createStep } = init({
|
|
28
|
+
apiKey: 'pk_live_your_api_key_here',
|
|
29
|
+
pinId: 'pin-abc123', // Target pin for updates
|
|
30
|
+
// OR projectId: 'project-xyz' // Alternative to pinId
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Local testing (override backendUrl)
|
|
34
|
+
const { createWorkflow, createStep } = init({
|
|
35
|
+
apiKey: 'pk_test_your_api_key_here',
|
|
36
|
+
backendUrl: 'http://localhost:8000', // Override for local dev
|
|
37
|
+
pinId: 'pin-abc123',
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Create Workflow
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { z } from 'zod';
|
|
45
|
+
|
|
46
|
+
const fetchWeather = createStep({
|
|
47
|
+
id: 'fetch-weather',
|
|
48
|
+
description: 'Fetches weather data',
|
|
49
|
+
inputSchema: z.object({ city: z.string() }),
|
|
50
|
+
outputSchema: z.object({ temp: z.number() }),
|
|
51
|
+
execute: async ({ inputData }) => {
|
|
52
|
+
// Your step logic
|
|
53
|
+
return { temp: 25 };
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const myWorkflow = createWorkflow({
|
|
58
|
+
id: 'weather-workflow',
|
|
59
|
+
inputSchema: z.object({ city: z.string() }),
|
|
60
|
+
outputSchema: z.object({ temp: z.number() }),
|
|
61
|
+
})
|
|
62
|
+
.then(fetchWeather);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3. Execute Workflow
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const run = await myWorkflow.createRun();
|
|
69
|
+
const result = await run.start({ city: 'New York' });
|
|
70
|
+
// Events are automatically published to Pindown.ai backend API
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## How It Works
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
┌─────────────────┐
|
|
77
|
+
│ User's Code │
|
|
78
|
+
│ (Your Server) │
|
|
79
|
+
│ │
|
|
80
|
+
│ Workflow runs │──┐
|
|
81
|
+
│ @mastra/pindown│ │ HTTP POST with API key
|
|
82
|
+
│ publishes │──┼─────────────────┐
|
|
83
|
+
└─────────────────┘ │ │
|
|
84
|
+
│ ▼
|
|
85
|
+
┌──────────────┐
|
|
86
|
+
│ Pindown.ai │
|
|
87
|
+
│ Backend API │
|
|
88
|
+
│ │
|
|
89
|
+
│ - Validates │
|
|
90
|
+
│ API key │
|
|
91
|
+
│ - Counts │
|
|
92
|
+
│ requests │
|
|
93
|
+
│ - Writes to │
|
|
94
|
+
│ Firebase │
|
|
95
|
+
└──────┬───────┘
|
|
96
|
+
│
|
|
97
|
+
│ Real-time updates
|
|
98
|
+
▼
|
|
99
|
+
┌──────────────┐
|
|
100
|
+
│ Firebase │
|
|
101
|
+
│ Realtime DB │
|
|
102
|
+
└──────┬───────┘
|
|
103
|
+
│
|
|
104
|
+
│ Subscribe
|
|
105
|
+
▼
|
|
106
|
+
┌──────────────┐
|
|
107
|
+
│ Frontend │
|
|
108
|
+
│ (React) │
|
|
109
|
+
└──────────────┘
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Backend API Endpoint
|
|
113
|
+
|
|
114
|
+
The package publishes to: `POST /api/workflows/events`
|
|
115
|
+
|
|
116
|
+
**Headers:**
|
|
117
|
+
- `Authorization: Bearer {apiKey}`
|
|
118
|
+
- `Content-Type: application/json`
|
|
119
|
+
|
|
120
|
+
**Body:**
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"runId": "run-abc123",
|
|
124
|
+
"workflowId": "weather-workflow",
|
|
125
|
+
"event": {
|
|
126
|
+
"type": "step.completed",
|
|
127
|
+
"stepId": "fetch-weather",
|
|
128
|
+
"output": {...},
|
|
129
|
+
"timestamp": 1234567890
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Frontend Subscription
|
|
135
|
+
|
|
136
|
+
Your frontend can subscribe to workflow updates using Firebase:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { ref, onValue } from 'firebase/database';
|
|
140
|
+
|
|
141
|
+
const eventsRef = ref(db, `workflow_runs/${runId}/events`);
|
|
142
|
+
onValue(eventsRef, (snapshot) => {
|
|
143
|
+
const events = snapshot.val();
|
|
144
|
+
// Handle real-time workflow events
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Security
|
|
149
|
+
|
|
150
|
+
- ✅ API key validation on every request
|
|
151
|
+
- ✅ Request counting for billing/limits
|
|
152
|
+
- ✅ Firebase security rules ensure users only see their own runs
|
|
153
|
+
- ✅ No direct Firebase access from user's code
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';var events=require('@mastra/core/events'),workflows=require('@mastra/core/workflows');var x=Object.defineProperty;var f=n=>{throw TypeError(n)};var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var P=(n,e)=>{for(var t in e)x(n,t,{get:e[t],enumerable:true});};var g=(n,e,t)=>e.has(n)||f("Cannot "+t);var T=(n,e,t)=>(g(n,e,"read from private field"),t?t.call(n):e.get(n)),d=(n,e,t)=>e.has(n)?f("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),y=(n,e,t,i)=>(g(n,e,"write to private field"),e.set(n,t),t);exports.PindownPubSub=void 0;var m=S(()=>{exports.PindownPubSub=class extends events.PubSub{constructor(e){super(),this.apiKey=e.apiKey,this.backendUrl=(e.backendUrl||"http://api.pindown.ai").replace(/\/$/,""),this.workflowId=e.workflowId,this.runId=e.runId,this.pinId=e.pinId,this.projectId=e.projectId;}async publish(e,t){if(!e.match(/^workflow\.events\.v2\.(.+)$/))return;let p={type:t.type,runId:this.runId,workflowId:this.workflowId,...t.data,timestamp:Date.now(),createdAt:new Date().toISOString()};try{let r=await fetch(`${this.backendUrl}/api/workflows/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({runId:this.runId,workflowId:this.workflowId,pinId:this.pinId,projectId:this.projectId,event:p})});if(!r.ok){let a=await r.text();console.error("PindownPubSub: Failed to publish event",{status:r.status,statusText:r.statusText,error:a,eventType:t.type});}}catch(r){console.error("PindownPubSub: Error publishing event",{error:r.message||String(r),eventType:t.type});}}async subscribe(e,t){}async unsubscribe(e,t){}async flush(){}async close(){}};});var k={};P(k,{PindownRun:()=>exports.PindownRun});var w;exports.PindownRun=void 0;var b=S(()=>{m();exports.PindownRun=class extends workflows.Run{constructor(t,i){super(t);this._pubsub=null;d(this,w);this.apiKey=i.apiKey,this.backendUrl=i.backendUrl,this.workflowId=t.workflowId,this.pinId=i.pinId,this.projectId=i.projectId,this.serializedStepGraph=t.serializedStepGraph||[],y(this,w,t.mastra);}get pubsub(){if(!this._pubsub)throw new Error("PubSub not initialized. Call initializePubSub() first.");return this._pubsub}initializePubSub(){this._pubsub||(this._pubsub=new exports.PindownPubSub({apiKey:this.apiKey,backendUrl:this.backendUrl,workflowId:this.workflowId,runId:this.runId,pinId:this.pinId,projectId:this.projectId}),this.executionEngine.pubsub=this._pubsub);}async start(t){this.initializePubSub(),this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.started",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,inputData:t,stepGraph:this.serializedStepGraph}});try{let i=await super.start({inputData:t});return this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.completed",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,output:i}}),i}catch(i){throw this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.failed",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,error:i.message||String(i)}}),i}}getPubSub(){return this._pubsub}};w=new WeakMap;});m();var h=class extends workflows.DefaultExecutionEngine{constructor(e,t){super({mastra:e,options:t});}async executeStep(e,t,i){let p,r,a,o;if(typeof e=="string")p=e,r=t,a=i,o=a?.runId||a?.params?.runId||"";else {let s=e;p=s.stepId,r=s.step,a=s.context||s,o=a?.runId||a?.params?.runId||"";}this.pubsub&&o&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.started",runId:o,data:{stepId:p,inputData:a?.inputData}});try{let s=typeof e=="string"?await super.executeStep({stepId:p,step:r,context:a}):await super.executeStep(e);return this.pubsub&&o&&s?.status==="completed"&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.completed",runId:o,data:{stepId:p,output:s?.output}}),s}catch(s){throw this.pubsub&&o&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.failed",runId:o,data:{stepId:p,error:s.message||String(s)}}),s}}};var u,l=class extends workflows.Workflow{constructor(t,i){super(t);d(this,u);this.engineType="pindown",this.apiKey=i.apiKey,this.backendUrl=i.backendUrl||"http://api.pindown.ai",this.pinId=i.pinId,this.projectId=i.projectId;}__registerMastra(t){super.__registerMastra(t),y(this,u,t);this.executionEngine;this.executionEngine=new h(t,{validateInputs:this.options?.validateInputs??true,shouldPersistSnapshot:()=>false}),this.executionEngine.__registerMastra(t);}getApiKey(){return this.apiKey}getBackendUrl(){return this.backendUrl}getPinId(){return this.pinId}getProjectId(){return this.projectId}async createRun(t){let i=t?.runId;if(!i)try{i=(await import('crypto')).randomUUID();}catch{i=`${Date.now()}-${Math.random().toString(36).substring(2,15)}`;}let{PindownRun:p}=await Promise.resolve().then(()=>(b(),k)),r=new p({workflowId:this.id,runId:i,resourceId:t?.resourceId,executionEngine:this.executionEngine,executionGraph:this.executionGraph,serializedStepGraph:this.serializedStepGraph,mastra:T(this,u),workflowSteps:this.steps||this.workflowSteps,workflowEngineType:this.engineType,validateInputs:this.options?.validateInputs},{apiKey:this.apiKey,backendUrl:this.backendUrl,pinId:this.pinId,projectId:this.projectId});return this.runs&&this.runs.set(i,r),r}};u=new WeakMap;b();function v(n){return {id:n.id,description:n.description,inputSchema:n.inputSchema,stateSchema:n.stateSchema,outputSchema:n.outputSchema,resumeSchema:n.resumeSchema,suspendSchema:n.suspendSchema,scorers:n.scorers,retries:n.retries,execute:n.execute.bind(n)}}function K(n){return {createWorkflow(e){return new l(e,n)},createStep:v}}
|
|
2
|
+
exports.PindownExecutionEngine=h;exports.PindownWorkflow=l;exports.init=K;//# sourceMappingURL=index.cjs.map
|
|
3
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pubsub.ts","../src/run.ts","../src/index.ts","../src/execution-engine.ts","../src/workflow.ts","../src/step.ts","../src/init.ts"],"names":["PindownPubSub","init_pubsub","__esmMin","PubSub","config","topic","event","eventData","response","errorText","error","cb","run_exports","__export","PindownRun","_mastra","init_run","Run","params","__privateAdd","__privateSet","inputData","result","PindownExecutionEngine","DefaultExecutionEngine","mastra","options","paramsOrStepId","step","context","stepId","stepToExecute","executionContext","runId","PindownWorkflow","Workflow","runIdToUse","pindownRun","__privateGet","createStep","init"],"mappings":"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","file":"index.cjs","sourcesContent":["import { PubSub } from '@mastra/core/events';\nimport type { Event } from '@mastra/core/events';\nimport type { PindownPubSubConfig } from './types';\n\n/**\n * PindownPubSub - HTTP-based PubSub that publishes to Pindown.ai backend API\n * \n * Users install this package and wrap their Mastra workflows.\n * The package publishes workflow events to Pindown.ai backend API,\n * which validates API keys, counts requests, and writes to Firebase.\n * \n * Flow:\n * 1. User's workflow executes\n * 2. PindownPubSub.publish() makes HTTP POST to backend API\n * 3. Backend validates API key, counts request, writes to Firebase\n * 4. Frontend subscribes to Firebase for real-time updates\n */\nexport class PindownPubSub extends PubSub {\n private apiKey: string;\n private backendUrl: string;\n private workflowId: string;\n private runId: string;\n private pinId?: string;\n private projectId?: string;\n\n constructor(config: PindownPubSubConfig) {\n super();\n this.apiKey = config.apiKey;\n // Default to production API, allow override for local testing\n this.backendUrl = (config.backendUrl || 'http://api.pindown.ai').replace(/\\/$/, ''); // Remove trailing slash\n this.workflowId = config.workflowId;\n this.runId = config.runId;\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n }\n\n /**\n * Publish event to Pindown.ai backend API\n * \n * Topic format: \"workflow.events.v2.{runId}\"\n * Backend API endpoint: POST /api/workflows/events\n * \n * Backend will:\n * - Validate API key\n * - Count request (for billing/limits)\n * - Write to Firebase Realtime Database\n */\n async publish(topic: string, event: Omit<Event, 'id' | 'createdAt'>): Promise<void> {\n // Parse topic to extract runId\n // Topic format: \"workflow.events.v2.{runId}\"\n const match = topic.match(/^workflow\\.events\\.v2\\.(.+)$/);\n if (!match) {\n return; // Ignore non-workflow topics\n }\n\n const eventData = {\n type: event.type,\n runId: this.runId,\n workflowId: this.workflowId,\n ...event.data,\n timestamp: Date.now(),\n createdAt: new Date().toISOString(),\n };\n\n try {\n // POST to backend API with API key\n const response = await fetch(`${this.backendUrl}/api/workflows/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n runId: this.runId,\n workflowId: this.workflowId,\n pinId: this.pinId,\n projectId: this.projectId,\n event: eventData,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`PindownPubSub: Failed to publish event`, {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n eventType: event.type,\n });\n // Don't throw - publishing failures shouldn't break workflow execution\n }\n } catch (error: any) {\n // Log but don't throw - publishing failures shouldn't break workflow execution\n console.error('PindownPubSub: Error publishing event', {\n error: error.message || String(error),\n eventType: event.type,\n });\n }\n }\n\n /**\n * Subscribe - Not needed on backend, frontend subscribes directly to Firebase\n * This is just for API compatibility with PubSub interface\n */\n async subscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n // Backend doesn't subscribe - frontend does via Firebase listeners\n // This is just for API compatibility with PubSub interface\n }\n\n /**\n * Unsubscribe - No-op on backend\n */\n async unsubscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n // No-op on backend\n }\n\n /**\n * Flush - No-op for Firebase\n */\n async flush(): Promise<void> {\n // No-op\n }\n\n /**\n * Close - Cleanup (no-op for Firebase)\n */\n async close(): Promise<void> {\n // No-op\n }\n}\n","/**\n * PindownRun - Run class with Firebase PubSub integration\n * \n * Extends base Run class and publishes events to Firebase during execution.\n * This is where the magic happens - step updates are published to Firebase\n * so the frontend can subscribe in real-time.\n */\n\nimport type { Mastra } from '@mastra/core/mastra';\nimport { Run } from '@mastra/core/workflows';\nimport type {\n Step,\n ExecutionEngine,\n ExecutionGraph,\n SerializedStepFlowEntry,\n StepWithComponent,\n WorkflowEngineType,\n} from '@mastra/core/workflows';\nimport { PindownPubSub } from './pubsub';\nimport type { PindownEngineType } from './types';\n\nexport class PindownRun<\n TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n >[],\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n> extends Run<PindownEngineType, TSteps, TState, TInput, TOutput> {\n private apiKey: string;\n private backendUrl: string;\n public workflowId: string;\n private pinId?: string;\n private projectId?: string;\n private _pubsub: PindownPubSub | null = null;\n \n // Override pubsub property to satisfy base class type\n // @ts-expect-error - Base class expects PubSub, we use PindownPubSub | null\n public get pubsub(): PindownPubSub {\n if (!this._pubsub) {\n throw new Error('PubSub not initialized. Call initializePubSub() first.');\n }\n return this._pubsub;\n }\n public serializedStepGraph: SerializedStepFlowEntry[];\n #mastra: Mastra | undefined;\n\n constructor(\n params: {\n workflowId: string;\n runId: string;\n resourceId?: string;\n executionEngine: ExecutionEngine;\n executionGraph: ExecutionGraph;\n serializedStepGraph: SerializedStepFlowEntry[];\n mastra?: Mastra;\n retryConfig?: {\n attempts?: number;\n delay?: number;\n };\n cleanup?: () => void;\n workflowSteps: Record<string, StepWithComponent>;\n workflowEngineType: WorkflowEngineType;\n validateInputs?: boolean;\n },\n config: {\n apiKey: string;\n backendUrl: string;\n pinId?: string;\n projectId?: string;\n }\n ) {\n super(params);\n this.apiKey = config.apiKey;\n this.backendUrl = config.backendUrl;\n this.workflowId = params.workflowId;\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n this.serializedStepGraph = params.serializedStepGraph || [];\n this.#mastra = params.mastra;\n }\n\n /**\n * Initialize PubSub for this run\n * Called before workflow execution starts\n */\n private initializePubSub(): void {\n if (!this._pubsub) {\n this._pubsub = new PindownPubSub({\n apiKey: this.apiKey,\n backendUrl: this.backendUrl,\n workflowId: this.workflowId,\n runId: this.runId,\n pinId: this.pinId,\n projectId: this.projectId,\n });\n\n // Attach pubsub to execution engine so it can publish events\n // This is a hook that allows the execution engine to publish step updates\n (this.executionEngine as any).pubsub = this._pubsub;\n }\n }\n\n /**\n * Start workflow execution with Firebase PubSub\n * \n * Overrides base start() to initialize PubSub and publish workflow events\n */\n // @ts-expect-error - Base class has different signature, but runtime works\n async start(inputData: TInput): Promise<any> {\n // Initialize PubSub before starting\n this.initializePubSub();\n\n // Publish workflow started event with step graph\n // This allows the frontend to visualize the workflow structure before execution\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.started',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n inputData,\n // Send the step graph so frontend can visualize the workflow structure\n stepGraph: this.serializedStepGraph,\n },\n } as any);\n }\n\n try {\n // Execute workflow (base class handles step execution)\n // The execution engine will publish step events via pubsub\n const result = await super.start({ inputData } as any);\n\n // Publish workflow completed event\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.completed',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n output: result,\n },\n } as any);\n }\n\n return result;\n } catch (error: any) {\n // Publish workflow failed event\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.failed',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n error: error.message || String(error),\n },\n } as any);\n }\n\n throw error;\n }\n }\n\n /**\n * Get PubSub instance (for testing/debugging)\n */\n getPubSub(): PindownPubSub | null {\n return this._pubsub;\n }\n}\n","/**\n * @mastra/pindown\n * \n * Mastra workflow integration for Pindown.ai with Firebase Realtime Database PubSub\n * \n * Provides:\n * - PindownPubSub: Firebase-based PubSub implementation\n * - PindownWorkflow: Workflow class with Firebase integration\n * - PindownRun: Run class that publishes events to Firebase\n * - init(): Helper function to create workflow and step factories\n */\n\nexport * from './pubsub';\nexport * from './workflow';\nexport * from './run';\nexport * from './execution-engine';\nexport * from './types';\nexport { init } from './init';\n","/**\n * PindownExecutionEngine - Execution engine with Firebase PubSub integration\n * \n * Extends default execution engine and hooks into step execution\n * to publish events to Firebase via PubSub.\n * \n * This is where step.started, step.completed, and step.failed events\n * are published to Firebase.\n */\n\nimport { DefaultExecutionEngine } from '@mastra/core/workflows';\nimport type {\n ExecutionEngineOptions,\n Step,\n StepResult,\n} from '@mastra/core/workflows';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { PindownPubSub } from './pubsub';\nimport type { PindownEngineType } from './types';\n\nexport class PindownExecutionEngine extends DefaultExecutionEngine {\n public pubsub?: PindownPubSub;\n\n constructor(mastra: Mastra, options: ExecutionEngineOptions) {\n super({ mastra, options });\n }\n\n /**\n * Override executeStep to publish events to Firebase\n * \n * This hooks into step execution to publish:\n * - step.started when step begins\n * - step.completed when step succeeds\n * - step.failed when step fails\n */\n async executeStep<T>(\n paramsOrStepId: any,\n step?: Step<any, any, any, any, any, any, PindownEngineType>,\n context?: any\n ): Promise<any> {\n // Handle both old API (stepId, step, context) and new API (params object)\n let stepId: string;\n let stepToExecute: Step<any, any, any, any, any, any, PindownEngineType>;\n let executionContext: any;\n let runId: string;\n\n if (typeof paramsOrStepId === 'string') {\n // Old API: executeStep(stepId, step, context)\n stepId = paramsOrStepId;\n stepToExecute = step!;\n executionContext = context!;\n runId = executionContext?.runId || executionContext?.params?.runId || '';\n } else {\n // New API: executeStep({ stepId, step, context })\n const params = paramsOrStepId;\n stepId = params.stepId;\n stepToExecute = params.step;\n executionContext = params.context || params;\n runId = executionContext?.runId || executionContext?.params?.runId || '';\n }\n\n // Publish step started event\n if (this.pubsub && runId) {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.started',\n runId,\n data: {\n stepId,\n inputData: executionContext?.inputData,\n },\n } as any);\n }\n\n try {\n // Execute step (base class handles the actual execution)\n const result = typeof paramsOrStepId === 'string'\n ? await super.executeStep({ stepId, step: stepToExecute, context: executionContext } as any)\n : await super.executeStep(paramsOrStepId);\n\n // Publish step completed event\n if (this.pubsub && runId && (result as any)?.status === 'completed') {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.completed',\n runId,\n data: {\n stepId,\n output: (result as any)?.output,\n },\n } as any);\n }\n\n return result;\n } catch (error: any) {\n // Publish step failed event\n if (this.pubsub && runId) {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.failed',\n runId,\n data: {\n stepId,\n error: error.message || String(error),\n },\n } as any);\n }\n\n throw error;\n }\n }\n}\n","import type { Mastra } from '@mastra/core/mastra';\nimport { Workflow } from '@mastra/core/workflows';\nimport type { Step } from '@mastra/core/workflows';\nimport type { PindownInitConfig } from './types';\nimport type { PindownEngineType } from './types';\nimport { PindownExecutionEngine } from './execution-engine';\n\n/**\n * PindownWorkflow - Workflow class with Pindown.ai backend API integration\n * \n * Extends base Workflow class and adds HTTP-based PubSub that publishes\n * to Pindown.ai backend API (with API key validation and request counting).\n */\nexport class PindownWorkflow<\n TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n >[],\n TWorkflowId extends string = string,\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n TPrevSchema = TInput,\n> extends Workflow<PindownEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrevSchema> {\n #mastra: Mastra | undefined;\n private apiKey: string;\n private backendUrl: string;\n private pinId?: string;\n private projectId?: string;\n\n constructor(\n params: {\n id: TWorkflowId;\n inputSchema: any;\n outputSchema: any;\n stateSchema?: any;\n steps?: TSteps;\n description?: string;\n options?: {\n validateInputs?: boolean;\n };\n },\n config: PindownInitConfig\n ) {\n super(params);\n // Set engineType on the base class (it's a protected property)\n (this as any).engineType = 'pindown';\n this.apiKey = config.apiKey;\n // Default to production API, allow override for local testing\n this.backendUrl = config.backendUrl || 'http://api.pindown.ai';\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n }\n\n __registerMastra(mastra: Mastra) {\n super.__registerMastra(mastra);\n this.#mastra = mastra;\n \n // Replace execution engine with PindownExecutionEngine\n // This ensures step events are published to Firebase\n const baseExecutionEngine = (this as any).executionEngine;\n (this as any).executionEngine = new PindownExecutionEngine(mastra, {\n validateInputs: (this as any).options?.validateInputs ?? true,\n shouldPersistSnapshot: () => false,\n });\n \n // Copy any necessary state from base engine\n // Register mastra with new engine\n (this as any).executionEngine.__registerMastra(mastra);\n }\n\n /**\n * Get API key (for debugging/testing)\n */\n getApiKey(): string {\n return this.apiKey;\n }\n\n /**\n * Get backend URL\n */\n getBackendUrl(): string {\n return this.backendUrl;\n }\n\n /**\n * Get pin ID\n */\n getPinId(): string | undefined {\n return this.pinId;\n }\n\n /**\n * Get project ID\n */\n getProjectId(): string | undefined {\n return this.projectId;\n }\n\n /**\n * Override createRun to pass config to PindownRun\n */\n // @ts-expect-error - Type mismatch with base class generics, but runtime works correctly\n async createRun(options?: {\n runId?: string;\n resourceId?: string;\n }) {\n // Generate runId if not provided\n let runIdToUse = options?.runId;\n if (!runIdToUse) {\n // Use crypto.randomUUID if available (Node.js 16+), otherwise fallback\n try {\n const crypto = await import('node:crypto');\n runIdToUse = crypto.randomUUID();\n } catch {\n // Fallback for environments without node:crypto\n runIdToUse = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;\n }\n }\n \n const { PindownRun } = await import('./run');\n const pindownRun = new PindownRun(\n {\n workflowId: (this as any).id, // Access id from base class\n runId: runIdToUse,\n resourceId: options?.resourceId,\n executionEngine: (this as any).executionEngine, // Access from base class\n executionGraph: (this as any).executionGraph,\n serializedStepGraph: (this as any).serializedStepGraph,\n mastra: this.#mastra,\n workflowSteps: (this as any).steps || (this as any).workflowSteps,\n workflowEngineType: (this as any).engineType, // Access from base class\n validateInputs: (this as any).options?.validateInputs, // Access from base class\n },\n {\n apiKey: this.apiKey,\n backendUrl: this.backendUrl,\n pinId: this.pinId,\n projectId: this.projectId,\n }\n );\n\n // Store run in workflow's runs map (if it exists)\n if ((this as any).runs) {\n (this as any).runs.set(runIdToUse, pindownRun);\n }\n\n return pindownRun;\n }\n}\n","/**\n * createStep - Factory function to create workflow steps\n * \n * For now, this is a simple pass-through that creates steps compatible with Pindown engine.\n * In the future, this can be extended to add Pindown-specific step features.\n */\n\nimport type { StepParams, Step } from '@mastra/core/workflows';\nimport type { PindownEngineType } from './types';\nimport type { ZodTypeAny } from 'zod';\n\n/**\n * Create a step from explicit params\n */\nexport function createStep<\n TStepId extends string,\n TStateSchema extends ZodTypeAny | undefined = any,\n TInputSchema extends ZodTypeAny | undefined = any,\n TOutputSchema extends ZodTypeAny | undefined = any,\n TResumeSchema extends ZodTypeAny | undefined = undefined,\n TSuspendSchema extends ZodTypeAny | undefined = undefined,\n>(\n // @ts-expect-error - Type constraints don't match exactly, but runtime works\n params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>\n): Step<\n TStepId,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n> {\n return {\n id: params.id,\n description: params.description,\n inputSchema: params.inputSchema,\n stateSchema: params.stateSchema,\n outputSchema: params.outputSchema,\n resumeSchema: params.resumeSchema,\n suspendSchema: params.suspendSchema,\n scorers: params.scorers,\n retries: params.retries,\n execute: params.execute.bind(params),\n } as Step<any, any, any, any, any, any, PindownEngineType>;\n}\n","import type { Step } from '@mastra/core/workflows';\nimport { PindownWorkflow } from './workflow';\nimport { createStep } from './step';\nimport type { PindownInitConfig } from './types';\n\n/**\n * Initialize Pindown workflow helpers\n * \n * Similar to @mastra/inngest's init() function\n * Returns createWorkflow and createStep factories\n * \n * Users provide API key and backend URL.\n * The package will publish events to your backend API,\n * which validates API keys, counts requests, and writes to Firebase.\n * \n * @param config - Pindown configuration with API key and backend URL\n * @returns Object with createWorkflow and createStep functions\n * \n * @example\n * ```typescript\n * import { init } from '@mastra/pindown';\n * \n * // Production (defaults to http://api.pindown.ai)\n * const { createWorkflow, createStep } = init({\n * apiKey: 'pk_live_...',\n * pinId: 'pin-abc123' // or projectId: 'project-xyz'\n * });\n * \n * // Local testing\n * const { createWorkflow, createStep } = init({\n * apiKey: 'pk_test_...',\n * backendUrl: 'http://localhost:8000',\n * pinId: 'pin-abc123'\n * });\n * ```\n */\nexport function init(config: PindownInitConfig) {\n return {\n /**\n * Create a Pindown workflow\n */\n createWorkflow<\n TWorkflowId extends string = string,\n TState = any,\n TInput = any,\n TOutput = any,\n TSteps extends Step<string, any, any, any, any, any, 'pindown'>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n 'pindown'\n >[]\n >(params: {\n id: TWorkflowId;\n inputSchema: any;\n outputSchema: any;\n stateSchema?: any;\n steps?: TSteps;\n description?: string;\n options?: {\n validateInputs?: boolean;\n };\n }) {\n return new PindownWorkflow(params, config);\n },\n\n /**\n * Create a step (delegates to createStep)\n */\n createStep,\n };\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { PubSub, Event } from '@mastra/core/events';
|
|
2
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
3
|
+
import { Step, Run, SerializedStepFlowEntry, ExecutionEngine, ExecutionGraph, StepWithComponent, WorkflowEngineType, Workflow, DefaultExecutionEngine, ExecutionEngineOptions, StepParams } from '@mastra/core/workflows';
|
|
4
|
+
import { ZodTypeAny } from 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Engine type identifier for Pindown workflows
|
|
8
|
+
*/
|
|
9
|
+
type PindownEngineType = 'pindown';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for PindownPubSub
|
|
12
|
+
* Users provide API key and backend URL
|
|
13
|
+
*/
|
|
14
|
+
interface PindownPubSubConfig {
|
|
15
|
+
apiKey: string;
|
|
16
|
+
backendUrl?: string;
|
|
17
|
+
workflowId: string;
|
|
18
|
+
runId: string;
|
|
19
|
+
pinId?: string;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for Pindown workflow initialization
|
|
24
|
+
* Users provide API key and optionally backend URL
|
|
25
|
+
*/
|
|
26
|
+
interface PindownInitConfig {
|
|
27
|
+
apiKey: string;
|
|
28
|
+
backendUrl?: string;
|
|
29
|
+
pinId?: string;
|
|
30
|
+
projectId?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pindown workflow configuration
|
|
34
|
+
* Extends base workflow config with Pindown-specific options
|
|
35
|
+
*/
|
|
36
|
+
interface PindownWorkflowConfig<TWorkflowId extends string = string, TState = any, TInput = any, TOutput = any, TSteps extends any[] = any[]> {
|
|
37
|
+
id: TWorkflowId;
|
|
38
|
+
inputSchema: any;
|
|
39
|
+
outputSchema: any;
|
|
40
|
+
stateSchema?: any;
|
|
41
|
+
steps?: TSteps;
|
|
42
|
+
description?: string;
|
|
43
|
+
options?: {
|
|
44
|
+
validateInputs?: boolean;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* PindownPubSub - HTTP-based PubSub that publishes to Pindown.ai backend API
|
|
50
|
+
*
|
|
51
|
+
* Users install this package and wrap their Mastra workflows.
|
|
52
|
+
* The package publishes workflow events to Pindown.ai backend API,
|
|
53
|
+
* which validates API keys, counts requests, and writes to Firebase.
|
|
54
|
+
*
|
|
55
|
+
* Flow:
|
|
56
|
+
* 1. User's workflow executes
|
|
57
|
+
* 2. PindownPubSub.publish() makes HTTP POST to backend API
|
|
58
|
+
* 3. Backend validates API key, counts request, writes to Firebase
|
|
59
|
+
* 4. Frontend subscribes to Firebase for real-time updates
|
|
60
|
+
*/
|
|
61
|
+
declare class PindownPubSub extends PubSub {
|
|
62
|
+
private apiKey;
|
|
63
|
+
private backendUrl;
|
|
64
|
+
private workflowId;
|
|
65
|
+
private runId;
|
|
66
|
+
private pinId?;
|
|
67
|
+
private projectId?;
|
|
68
|
+
constructor(config: PindownPubSubConfig);
|
|
69
|
+
/**
|
|
70
|
+
* Publish event to Pindown.ai backend API
|
|
71
|
+
*
|
|
72
|
+
* Topic format: "workflow.events.v2.{runId}"
|
|
73
|
+
* Backend API endpoint: POST /api/workflows/events
|
|
74
|
+
*
|
|
75
|
+
* Backend will:
|
|
76
|
+
* - Validate API key
|
|
77
|
+
* - Count request (for billing/limits)
|
|
78
|
+
* - Write to Firebase Realtime Database
|
|
79
|
+
*/
|
|
80
|
+
publish(topic: string, event: Omit<Event, 'id' | 'createdAt'>): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe - Not needed on backend, frontend subscribes directly to Firebase
|
|
83
|
+
* This is just for API compatibility with PubSub interface
|
|
84
|
+
*/
|
|
85
|
+
subscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Unsubscribe - No-op on backend
|
|
88
|
+
*/
|
|
89
|
+
unsubscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Flush - No-op for Firebase
|
|
92
|
+
*/
|
|
93
|
+
flush(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Close - Cleanup (no-op for Firebase)
|
|
96
|
+
*/
|
|
97
|
+
close(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* PindownRun - Run class with Firebase PubSub integration
|
|
102
|
+
*
|
|
103
|
+
* Extends base Run class and publishes events to Firebase during execution.
|
|
104
|
+
* This is where the magic happens - step updates are published to Firebase
|
|
105
|
+
* so the frontend can subscribe in real-time.
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
declare class PindownRun<TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<string, any, any, any, any, any, PindownEngineType>[], TState = unknown, TInput = unknown, TOutput = unknown> extends Run<PindownEngineType, TSteps, TState, TInput, TOutput> {
|
|
109
|
+
#private;
|
|
110
|
+
private apiKey;
|
|
111
|
+
private backendUrl;
|
|
112
|
+
workflowId: string;
|
|
113
|
+
private pinId?;
|
|
114
|
+
private projectId?;
|
|
115
|
+
private _pubsub;
|
|
116
|
+
get pubsub(): PindownPubSub;
|
|
117
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
118
|
+
constructor(params: {
|
|
119
|
+
workflowId: string;
|
|
120
|
+
runId: string;
|
|
121
|
+
resourceId?: string;
|
|
122
|
+
executionEngine: ExecutionEngine;
|
|
123
|
+
executionGraph: ExecutionGraph;
|
|
124
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
125
|
+
mastra?: Mastra;
|
|
126
|
+
retryConfig?: {
|
|
127
|
+
attempts?: number;
|
|
128
|
+
delay?: number;
|
|
129
|
+
};
|
|
130
|
+
cleanup?: () => void;
|
|
131
|
+
workflowSteps: Record<string, StepWithComponent>;
|
|
132
|
+
workflowEngineType: WorkflowEngineType;
|
|
133
|
+
validateInputs?: boolean;
|
|
134
|
+
}, config: {
|
|
135
|
+
apiKey: string;
|
|
136
|
+
backendUrl: string;
|
|
137
|
+
pinId?: string;
|
|
138
|
+
projectId?: string;
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* Initialize PubSub for this run
|
|
142
|
+
* Called before workflow execution starts
|
|
143
|
+
*/
|
|
144
|
+
private initializePubSub;
|
|
145
|
+
/**
|
|
146
|
+
* Start workflow execution with Firebase PubSub
|
|
147
|
+
*
|
|
148
|
+
* Overrides base start() to initialize PubSub and publish workflow events
|
|
149
|
+
*/
|
|
150
|
+
start(inputData: TInput): Promise<any>;
|
|
151
|
+
/**
|
|
152
|
+
* Get PubSub instance (for testing/debugging)
|
|
153
|
+
*/
|
|
154
|
+
getPubSub(): PindownPubSub | null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* PindownWorkflow - Workflow class with Pindown.ai backend API integration
|
|
159
|
+
*
|
|
160
|
+
* Extends base Workflow class and adds HTTP-based PubSub that publishes
|
|
161
|
+
* to Pindown.ai backend API (with API key validation and request counting).
|
|
162
|
+
*/
|
|
163
|
+
declare class PindownWorkflow<TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<string, any, any, any, any, any, PindownEngineType>[], TWorkflowId extends string = string, TState = unknown, TInput = unknown, TOutput = unknown, TPrevSchema = TInput> extends Workflow<PindownEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrevSchema> {
|
|
164
|
+
#private;
|
|
165
|
+
private apiKey;
|
|
166
|
+
private backendUrl;
|
|
167
|
+
private pinId?;
|
|
168
|
+
private projectId?;
|
|
169
|
+
constructor(params: {
|
|
170
|
+
id: TWorkflowId;
|
|
171
|
+
inputSchema: any;
|
|
172
|
+
outputSchema: any;
|
|
173
|
+
stateSchema?: any;
|
|
174
|
+
steps?: TSteps;
|
|
175
|
+
description?: string;
|
|
176
|
+
options?: {
|
|
177
|
+
validateInputs?: boolean;
|
|
178
|
+
};
|
|
179
|
+
}, config: PindownInitConfig);
|
|
180
|
+
__registerMastra(mastra: Mastra): void;
|
|
181
|
+
/**
|
|
182
|
+
* Get API key (for debugging/testing)
|
|
183
|
+
*/
|
|
184
|
+
getApiKey(): string;
|
|
185
|
+
/**
|
|
186
|
+
* Get backend URL
|
|
187
|
+
*/
|
|
188
|
+
getBackendUrl(): string;
|
|
189
|
+
/**
|
|
190
|
+
* Get pin ID
|
|
191
|
+
*/
|
|
192
|
+
getPinId(): string | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* Get project ID
|
|
195
|
+
*/
|
|
196
|
+
getProjectId(): string | undefined;
|
|
197
|
+
/**
|
|
198
|
+
* Override createRun to pass config to PindownRun
|
|
199
|
+
*/
|
|
200
|
+
createRun(options?: {
|
|
201
|
+
runId?: string;
|
|
202
|
+
resourceId?: string;
|
|
203
|
+
}): Promise<PindownRun<Step<string, any, any, any, any, any, "pindown">[], unknown, unknown, unknown>>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* PindownExecutionEngine - Execution engine with Firebase PubSub integration
|
|
208
|
+
*
|
|
209
|
+
* Extends default execution engine and hooks into step execution
|
|
210
|
+
* to publish events to Firebase via PubSub.
|
|
211
|
+
*
|
|
212
|
+
* This is where step.started, step.completed, and step.failed events
|
|
213
|
+
* are published to Firebase.
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
declare class PindownExecutionEngine extends DefaultExecutionEngine {
|
|
217
|
+
pubsub?: PindownPubSub;
|
|
218
|
+
constructor(mastra: Mastra, options: ExecutionEngineOptions);
|
|
219
|
+
/**
|
|
220
|
+
* Override executeStep to publish events to Firebase
|
|
221
|
+
*
|
|
222
|
+
* This hooks into step execution to publish:
|
|
223
|
+
* - step.started when step begins
|
|
224
|
+
* - step.completed when step succeeds
|
|
225
|
+
* - step.failed when step fails
|
|
226
|
+
*/
|
|
227
|
+
executeStep<T>(paramsOrStepId: any, step?: Step<any, any, any, any, any, any, PindownEngineType>, context?: any): Promise<any>;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* createStep - Factory function to create workflow steps
|
|
232
|
+
*
|
|
233
|
+
* For now, this is a simple pass-through that creates steps compatible with Pindown engine.
|
|
234
|
+
* In the future, this can be extended to add Pindown-specific step features.
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create a step from explicit params
|
|
239
|
+
*/
|
|
240
|
+
declare function createStep<TStepId extends string, TStateSchema extends ZodTypeAny | undefined = any, TInputSchema extends ZodTypeAny | undefined = any, TOutputSchema extends ZodTypeAny | undefined = any, TResumeSchema extends ZodTypeAny | undefined = undefined, TSuspendSchema extends ZodTypeAny | undefined = undefined>(params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>): Step<TStepId, any, any, any, any, any, PindownEngineType>;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Initialize Pindown workflow helpers
|
|
244
|
+
*
|
|
245
|
+
* Similar to @mastra/inngest's init() function
|
|
246
|
+
* Returns createWorkflow and createStep factories
|
|
247
|
+
*
|
|
248
|
+
* Users provide API key and backend URL.
|
|
249
|
+
* The package will publish events to your backend API,
|
|
250
|
+
* which validates API keys, counts requests, and writes to Firebase.
|
|
251
|
+
*
|
|
252
|
+
* @param config - Pindown configuration with API key and backend URL
|
|
253
|
+
* @returns Object with createWorkflow and createStep functions
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* import { init } from '@mastra/pindown';
|
|
258
|
+
*
|
|
259
|
+
* // Production (defaults to http://api.pindown.ai)
|
|
260
|
+
* const { createWorkflow, createStep } = init({
|
|
261
|
+
* apiKey: 'pk_live_...',
|
|
262
|
+
* pinId: 'pin-abc123' // or projectId: 'project-xyz'
|
|
263
|
+
* });
|
|
264
|
+
*
|
|
265
|
+
* // Local testing
|
|
266
|
+
* const { createWorkflow, createStep } = init({
|
|
267
|
+
* apiKey: 'pk_test_...',
|
|
268
|
+
* backendUrl: 'http://localhost:8000',
|
|
269
|
+
* pinId: 'pin-abc123'
|
|
270
|
+
* });
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare function init(config: PindownInitConfig): {
|
|
274
|
+
/**
|
|
275
|
+
* Create a Pindown workflow
|
|
276
|
+
*/
|
|
277
|
+
createWorkflow<TWorkflowId extends string = string, TState = any, TInput = any, TOutput = any, TSteps extends Step<string, any, any, any, any, any, "pindown">[] = Step<string, any, any, any, any, any, "pindown">[]>(params: {
|
|
278
|
+
id: TWorkflowId;
|
|
279
|
+
inputSchema: any;
|
|
280
|
+
outputSchema: any;
|
|
281
|
+
stateSchema?: any;
|
|
282
|
+
steps?: TSteps;
|
|
283
|
+
description?: string;
|
|
284
|
+
options?: {
|
|
285
|
+
validateInputs?: boolean;
|
|
286
|
+
};
|
|
287
|
+
}): PindownWorkflow<TSteps, TWorkflowId, unknown, unknown, unknown, unknown>;
|
|
288
|
+
/**
|
|
289
|
+
* Create a step (delegates to createStep)
|
|
290
|
+
*/
|
|
291
|
+
createStep: typeof createStep;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export { type PindownEngineType, PindownExecutionEngine, type PindownInitConfig, PindownPubSub, type PindownPubSubConfig, PindownRun, PindownWorkflow, type PindownWorkflowConfig, init };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { PubSub, Event } from '@mastra/core/events';
|
|
2
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
3
|
+
import { Step, Run, SerializedStepFlowEntry, ExecutionEngine, ExecutionGraph, StepWithComponent, WorkflowEngineType, Workflow, DefaultExecutionEngine, ExecutionEngineOptions, StepParams } from '@mastra/core/workflows';
|
|
4
|
+
import { ZodTypeAny } from 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Engine type identifier for Pindown workflows
|
|
8
|
+
*/
|
|
9
|
+
type PindownEngineType = 'pindown';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for PindownPubSub
|
|
12
|
+
* Users provide API key and backend URL
|
|
13
|
+
*/
|
|
14
|
+
interface PindownPubSubConfig {
|
|
15
|
+
apiKey: string;
|
|
16
|
+
backendUrl?: string;
|
|
17
|
+
workflowId: string;
|
|
18
|
+
runId: string;
|
|
19
|
+
pinId?: string;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for Pindown workflow initialization
|
|
24
|
+
* Users provide API key and optionally backend URL
|
|
25
|
+
*/
|
|
26
|
+
interface PindownInitConfig {
|
|
27
|
+
apiKey: string;
|
|
28
|
+
backendUrl?: string;
|
|
29
|
+
pinId?: string;
|
|
30
|
+
projectId?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pindown workflow configuration
|
|
34
|
+
* Extends base workflow config with Pindown-specific options
|
|
35
|
+
*/
|
|
36
|
+
interface PindownWorkflowConfig<TWorkflowId extends string = string, TState = any, TInput = any, TOutput = any, TSteps extends any[] = any[]> {
|
|
37
|
+
id: TWorkflowId;
|
|
38
|
+
inputSchema: any;
|
|
39
|
+
outputSchema: any;
|
|
40
|
+
stateSchema?: any;
|
|
41
|
+
steps?: TSteps;
|
|
42
|
+
description?: string;
|
|
43
|
+
options?: {
|
|
44
|
+
validateInputs?: boolean;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* PindownPubSub - HTTP-based PubSub that publishes to Pindown.ai backend API
|
|
50
|
+
*
|
|
51
|
+
* Users install this package and wrap their Mastra workflows.
|
|
52
|
+
* The package publishes workflow events to Pindown.ai backend API,
|
|
53
|
+
* which validates API keys, counts requests, and writes to Firebase.
|
|
54
|
+
*
|
|
55
|
+
* Flow:
|
|
56
|
+
* 1. User's workflow executes
|
|
57
|
+
* 2. PindownPubSub.publish() makes HTTP POST to backend API
|
|
58
|
+
* 3. Backend validates API key, counts request, writes to Firebase
|
|
59
|
+
* 4. Frontend subscribes to Firebase for real-time updates
|
|
60
|
+
*/
|
|
61
|
+
declare class PindownPubSub extends PubSub {
|
|
62
|
+
private apiKey;
|
|
63
|
+
private backendUrl;
|
|
64
|
+
private workflowId;
|
|
65
|
+
private runId;
|
|
66
|
+
private pinId?;
|
|
67
|
+
private projectId?;
|
|
68
|
+
constructor(config: PindownPubSubConfig);
|
|
69
|
+
/**
|
|
70
|
+
* Publish event to Pindown.ai backend API
|
|
71
|
+
*
|
|
72
|
+
* Topic format: "workflow.events.v2.{runId}"
|
|
73
|
+
* Backend API endpoint: POST /api/workflows/events
|
|
74
|
+
*
|
|
75
|
+
* Backend will:
|
|
76
|
+
* - Validate API key
|
|
77
|
+
* - Count request (for billing/limits)
|
|
78
|
+
* - Write to Firebase Realtime Database
|
|
79
|
+
*/
|
|
80
|
+
publish(topic: string, event: Omit<Event, 'id' | 'createdAt'>): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe - Not needed on backend, frontend subscribes directly to Firebase
|
|
83
|
+
* This is just for API compatibility with PubSub interface
|
|
84
|
+
*/
|
|
85
|
+
subscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Unsubscribe - No-op on backend
|
|
88
|
+
*/
|
|
89
|
+
unsubscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Flush - No-op for Firebase
|
|
92
|
+
*/
|
|
93
|
+
flush(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Close - Cleanup (no-op for Firebase)
|
|
96
|
+
*/
|
|
97
|
+
close(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* PindownRun - Run class with Firebase PubSub integration
|
|
102
|
+
*
|
|
103
|
+
* Extends base Run class and publishes events to Firebase during execution.
|
|
104
|
+
* This is where the magic happens - step updates are published to Firebase
|
|
105
|
+
* so the frontend can subscribe in real-time.
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
declare class PindownRun<TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<string, any, any, any, any, any, PindownEngineType>[], TState = unknown, TInput = unknown, TOutput = unknown> extends Run<PindownEngineType, TSteps, TState, TInput, TOutput> {
|
|
109
|
+
#private;
|
|
110
|
+
private apiKey;
|
|
111
|
+
private backendUrl;
|
|
112
|
+
workflowId: string;
|
|
113
|
+
private pinId?;
|
|
114
|
+
private projectId?;
|
|
115
|
+
private _pubsub;
|
|
116
|
+
get pubsub(): PindownPubSub;
|
|
117
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
118
|
+
constructor(params: {
|
|
119
|
+
workflowId: string;
|
|
120
|
+
runId: string;
|
|
121
|
+
resourceId?: string;
|
|
122
|
+
executionEngine: ExecutionEngine;
|
|
123
|
+
executionGraph: ExecutionGraph;
|
|
124
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
125
|
+
mastra?: Mastra;
|
|
126
|
+
retryConfig?: {
|
|
127
|
+
attempts?: number;
|
|
128
|
+
delay?: number;
|
|
129
|
+
};
|
|
130
|
+
cleanup?: () => void;
|
|
131
|
+
workflowSteps: Record<string, StepWithComponent>;
|
|
132
|
+
workflowEngineType: WorkflowEngineType;
|
|
133
|
+
validateInputs?: boolean;
|
|
134
|
+
}, config: {
|
|
135
|
+
apiKey: string;
|
|
136
|
+
backendUrl: string;
|
|
137
|
+
pinId?: string;
|
|
138
|
+
projectId?: string;
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* Initialize PubSub for this run
|
|
142
|
+
* Called before workflow execution starts
|
|
143
|
+
*/
|
|
144
|
+
private initializePubSub;
|
|
145
|
+
/**
|
|
146
|
+
* Start workflow execution with Firebase PubSub
|
|
147
|
+
*
|
|
148
|
+
* Overrides base start() to initialize PubSub and publish workflow events
|
|
149
|
+
*/
|
|
150
|
+
start(inputData: TInput): Promise<any>;
|
|
151
|
+
/**
|
|
152
|
+
* Get PubSub instance (for testing/debugging)
|
|
153
|
+
*/
|
|
154
|
+
getPubSub(): PindownPubSub | null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* PindownWorkflow - Workflow class with Pindown.ai backend API integration
|
|
159
|
+
*
|
|
160
|
+
* Extends base Workflow class and adds HTTP-based PubSub that publishes
|
|
161
|
+
* to Pindown.ai backend API (with API key validation and request counting).
|
|
162
|
+
*/
|
|
163
|
+
declare class PindownWorkflow<TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<string, any, any, any, any, any, PindownEngineType>[], TWorkflowId extends string = string, TState = unknown, TInput = unknown, TOutput = unknown, TPrevSchema = TInput> extends Workflow<PindownEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrevSchema> {
|
|
164
|
+
#private;
|
|
165
|
+
private apiKey;
|
|
166
|
+
private backendUrl;
|
|
167
|
+
private pinId?;
|
|
168
|
+
private projectId?;
|
|
169
|
+
constructor(params: {
|
|
170
|
+
id: TWorkflowId;
|
|
171
|
+
inputSchema: any;
|
|
172
|
+
outputSchema: any;
|
|
173
|
+
stateSchema?: any;
|
|
174
|
+
steps?: TSteps;
|
|
175
|
+
description?: string;
|
|
176
|
+
options?: {
|
|
177
|
+
validateInputs?: boolean;
|
|
178
|
+
};
|
|
179
|
+
}, config: PindownInitConfig);
|
|
180
|
+
__registerMastra(mastra: Mastra): void;
|
|
181
|
+
/**
|
|
182
|
+
* Get API key (for debugging/testing)
|
|
183
|
+
*/
|
|
184
|
+
getApiKey(): string;
|
|
185
|
+
/**
|
|
186
|
+
* Get backend URL
|
|
187
|
+
*/
|
|
188
|
+
getBackendUrl(): string;
|
|
189
|
+
/**
|
|
190
|
+
* Get pin ID
|
|
191
|
+
*/
|
|
192
|
+
getPinId(): string | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* Get project ID
|
|
195
|
+
*/
|
|
196
|
+
getProjectId(): string | undefined;
|
|
197
|
+
/**
|
|
198
|
+
* Override createRun to pass config to PindownRun
|
|
199
|
+
*/
|
|
200
|
+
createRun(options?: {
|
|
201
|
+
runId?: string;
|
|
202
|
+
resourceId?: string;
|
|
203
|
+
}): Promise<PindownRun<Step<string, any, any, any, any, any, "pindown">[], unknown, unknown, unknown>>;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* PindownExecutionEngine - Execution engine with Firebase PubSub integration
|
|
208
|
+
*
|
|
209
|
+
* Extends default execution engine and hooks into step execution
|
|
210
|
+
* to publish events to Firebase via PubSub.
|
|
211
|
+
*
|
|
212
|
+
* This is where step.started, step.completed, and step.failed events
|
|
213
|
+
* are published to Firebase.
|
|
214
|
+
*/
|
|
215
|
+
|
|
216
|
+
declare class PindownExecutionEngine extends DefaultExecutionEngine {
|
|
217
|
+
pubsub?: PindownPubSub;
|
|
218
|
+
constructor(mastra: Mastra, options: ExecutionEngineOptions);
|
|
219
|
+
/**
|
|
220
|
+
* Override executeStep to publish events to Firebase
|
|
221
|
+
*
|
|
222
|
+
* This hooks into step execution to publish:
|
|
223
|
+
* - step.started when step begins
|
|
224
|
+
* - step.completed when step succeeds
|
|
225
|
+
* - step.failed when step fails
|
|
226
|
+
*/
|
|
227
|
+
executeStep<T>(paramsOrStepId: any, step?: Step<any, any, any, any, any, any, PindownEngineType>, context?: any): Promise<any>;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* createStep - Factory function to create workflow steps
|
|
232
|
+
*
|
|
233
|
+
* For now, this is a simple pass-through that creates steps compatible with Pindown engine.
|
|
234
|
+
* In the future, this can be extended to add Pindown-specific step features.
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create a step from explicit params
|
|
239
|
+
*/
|
|
240
|
+
declare function createStep<TStepId extends string, TStateSchema extends ZodTypeAny | undefined = any, TInputSchema extends ZodTypeAny | undefined = any, TOutputSchema extends ZodTypeAny | undefined = any, TResumeSchema extends ZodTypeAny | undefined = undefined, TSuspendSchema extends ZodTypeAny | undefined = undefined>(params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>): Step<TStepId, any, any, any, any, any, PindownEngineType>;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Initialize Pindown workflow helpers
|
|
244
|
+
*
|
|
245
|
+
* Similar to @mastra/inngest's init() function
|
|
246
|
+
* Returns createWorkflow and createStep factories
|
|
247
|
+
*
|
|
248
|
+
* Users provide API key and backend URL.
|
|
249
|
+
* The package will publish events to your backend API,
|
|
250
|
+
* which validates API keys, counts requests, and writes to Firebase.
|
|
251
|
+
*
|
|
252
|
+
* @param config - Pindown configuration with API key and backend URL
|
|
253
|
+
* @returns Object with createWorkflow and createStep functions
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* import { init } from '@mastra/pindown';
|
|
258
|
+
*
|
|
259
|
+
* // Production (defaults to http://api.pindown.ai)
|
|
260
|
+
* const { createWorkflow, createStep } = init({
|
|
261
|
+
* apiKey: 'pk_live_...',
|
|
262
|
+
* pinId: 'pin-abc123' // or projectId: 'project-xyz'
|
|
263
|
+
* });
|
|
264
|
+
*
|
|
265
|
+
* // Local testing
|
|
266
|
+
* const { createWorkflow, createStep } = init({
|
|
267
|
+
* apiKey: 'pk_test_...',
|
|
268
|
+
* backendUrl: 'http://localhost:8000',
|
|
269
|
+
* pinId: 'pin-abc123'
|
|
270
|
+
* });
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare function init(config: PindownInitConfig): {
|
|
274
|
+
/**
|
|
275
|
+
* Create a Pindown workflow
|
|
276
|
+
*/
|
|
277
|
+
createWorkflow<TWorkflowId extends string = string, TState = any, TInput = any, TOutput = any, TSteps extends Step<string, any, any, any, any, any, "pindown">[] = Step<string, any, any, any, any, any, "pindown">[]>(params: {
|
|
278
|
+
id: TWorkflowId;
|
|
279
|
+
inputSchema: any;
|
|
280
|
+
outputSchema: any;
|
|
281
|
+
stateSchema?: any;
|
|
282
|
+
steps?: TSteps;
|
|
283
|
+
description?: string;
|
|
284
|
+
options?: {
|
|
285
|
+
validateInputs?: boolean;
|
|
286
|
+
};
|
|
287
|
+
}): PindownWorkflow<TSteps, TWorkflowId, unknown, unknown, unknown, unknown>;
|
|
288
|
+
/**
|
|
289
|
+
* Create a step (delegates to createStep)
|
|
290
|
+
*/
|
|
291
|
+
createStep: typeof createStep;
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
export { type PindownEngineType, PindownExecutionEngine, type PindownInitConfig, PindownPubSub, type PindownPubSubConfig, PindownRun, PindownWorkflow, type PindownWorkflowConfig, init };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {PubSub}from'@mastra/core/events';import {Run,DefaultExecutionEngine,Workflow}from'@mastra/core/workflows';var x=Object.defineProperty;var f=n=>{throw TypeError(n)};var S=(n,e)=>()=>(n&&(e=n(n=0)),e);var P=(n,e)=>{for(var t in e)x(n,t,{get:e[t],enumerable:true});};var g=(n,e,t)=>e.has(n)||f("Cannot "+t);var T=(n,e,t)=>(g(n,e,"read from private field"),t?t.call(n):e.get(n)),d=(n,e,t)=>e.has(n)?f("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(n):e.set(n,t),y=(n,e,t,i)=>(g(n,e,"write to private field"),e.set(n,t),t);var c,m=S(()=>{c=class extends PubSub{constructor(e){super(),this.apiKey=e.apiKey,this.backendUrl=(e.backendUrl||"http://api.pindown.ai").replace(/\/$/,""),this.workflowId=e.workflowId,this.runId=e.runId,this.pinId=e.pinId,this.projectId=e.projectId;}async publish(e,t){if(!e.match(/^workflow\.events\.v2\.(.+)$/))return;let p={type:t.type,runId:this.runId,workflowId:this.workflowId,...t.data,timestamp:Date.now(),createdAt:new Date().toISOString()};try{let r=await fetch(`${this.backendUrl}/api/workflows/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify({runId:this.runId,workflowId:this.workflowId,pinId:this.pinId,projectId:this.projectId,event:p})});if(!r.ok){let a=await r.text();console.error("PindownPubSub: Failed to publish event",{status:r.status,statusText:r.statusText,error:a,eventType:t.type});}}catch(r){console.error("PindownPubSub: Error publishing event",{error:r.message||String(r),eventType:t.type});}}async subscribe(e,t){}async unsubscribe(e,t){}async flush(){}async close(){}};});var k={};P(k,{PindownRun:()=>I});var w,I,b=S(()=>{m();I=class extends Run{constructor(t,i){super(t);this._pubsub=null;d(this,w);this.apiKey=i.apiKey,this.backendUrl=i.backendUrl,this.workflowId=t.workflowId,this.pinId=i.pinId,this.projectId=i.projectId,this.serializedStepGraph=t.serializedStepGraph||[],y(this,w,t.mastra);}get pubsub(){if(!this._pubsub)throw new Error("PubSub not initialized. Call initializePubSub() first.");return this._pubsub}initializePubSub(){this._pubsub||(this._pubsub=new c({apiKey:this.apiKey,backendUrl:this.backendUrl,workflowId:this.workflowId,runId:this.runId,pinId:this.pinId,projectId:this.projectId}),this.executionEngine.pubsub=this._pubsub);}async start(t){this.initializePubSub(),this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.started",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,inputData:t,stepGraph:this.serializedStepGraph}});try{let i=await super.start({inputData:t});return this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.completed",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,output:i}}),i}catch(i){throw this._pubsub&&await this._pubsub.publish(`workflow.events.v2.${this.runId}`,{type:"workflow.failed",runId:this.runId,data:{workflowId:this.workflowId,runId:this.runId,error:i.message||String(i)}}),i}}getPubSub(){return this._pubsub}};w=new WeakMap;});m();var h=class extends DefaultExecutionEngine{constructor(e,t){super({mastra:e,options:t});}async executeStep(e,t,i){let p,r,a,o;if(typeof e=="string")p=e,r=t,a=i,o=a?.runId||a?.params?.runId||"";else {let s=e;p=s.stepId,r=s.step,a=s.context||s,o=a?.runId||a?.params?.runId||"";}this.pubsub&&o&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.started",runId:o,data:{stepId:p,inputData:a?.inputData}});try{let s=typeof e=="string"?await super.executeStep({stepId:p,step:r,context:a}):await super.executeStep(e);return this.pubsub&&o&&s?.status==="completed"&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.completed",runId:o,data:{stepId:p,output:s?.output}}),s}catch(s){throw this.pubsub&&o&&await this.pubsub.publish(`workflow.events.v2.${o}`,{type:"step.failed",runId:o,data:{stepId:p,error:s.message||String(s)}}),s}}};var u,l=class extends Workflow{constructor(t,i){super(t);d(this,u);this.engineType="pindown",this.apiKey=i.apiKey,this.backendUrl=i.backendUrl||"http://api.pindown.ai",this.pinId=i.pinId,this.projectId=i.projectId;}__registerMastra(t){super.__registerMastra(t),y(this,u,t);this.executionEngine;this.executionEngine=new h(t,{validateInputs:this.options?.validateInputs??true,shouldPersistSnapshot:()=>false}),this.executionEngine.__registerMastra(t);}getApiKey(){return this.apiKey}getBackendUrl(){return this.backendUrl}getPinId(){return this.pinId}getProjectId(){return this.projectId}async createRun(t){let i=t?.runId;if(!i)try{i=(await import('crypto')).randomUUID();}catch{i=`${Date.now()}-${Math.random().toString(36).substring(2,15)}`;}let{PindownRun:p}=await Promise.resolve().then(()=>(b(),k)),r=new p({workflowId:this.id,runId:i,resourceId:t?.resourceId,executionEngine:this.executionEngine,executionGraph:this.executionGraph,serializedStepGraph:this.serializedStepGraph,mastra:T(this,u),workflowSteps:this.steps||this.workflowSteps,workflowEngineType:this.engineType,validateInputs:this.options?.validateInputs},{apiKey:this.apiKey,backendUrl:this.backendUrl,pinId:this.pinId,projectId:this.projectId});return this.runs&&this.runs.set(i,r),r}};u=new WeakMap;b();function v(n){return {id:n.id,description:n.description,inputSchema:n.inputSchema,stateSchema:n.stateSchema,outputSchema:n.outputSchema,resumeSchema:n.resumeSchema,suspendSchema:n.suspendSchema,scorers:n.scorers,retries:n.retries,execute:n.execute.bind(n)}}function K(n){return {createWorkflow(e){return new l(e,n)},createStep:v}}
|
|
2
|
+
export{h as PindownExecutionEngine,c as PindownPubSub,I as PindownRun,l as PindownWorkflow,K as init};//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pubsub.ts","../src/run.ts","../src/index.ts","../src/execution-engine.ts","../src/workflow.ts","../src/step.ts","../src/init.ts"],"names":["PindownPubSub","init_pubsub","__esmMin","PubSub","config","topic","event","eventData","response","errorText","error","cb","run_exports","__export","PindownRun","_mastra","init_run","Run","params","__privateAdd","__privateSet","inputData","result","PindownExecutionEngine","DefaultExecutionEngine","mastra","options","paramsOrStepId","step","context","stepId","stepToExecute","executionContext","runId","PindownWorkflow","Workflow","runIdToUse","pindownRun","__privateGet","createStep","init"],"mappings":"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","file":"index.js","sourcesContent":["import { PubSub } from '@mastra/core/events';\nimport type { Event } from '@mastra/core/events';\nimport type { PindownPubSubConfig } from './types';\n\n/**\n * PindownPubSub - HTTP-based PubSub that publishes to Pindown.ai backend API\n * \n * Users install this package and wrap their Mastra workflows.\n * The package publishes workflow events to Pindown.ai backend API,\n * which validates API keys, counts requests, and writes to Firebase.\n * \n * Flow:\n * 1. User's workflow executes\n * 2. PindownPubSub.publish() makes HTTP POST to backend API\n * 3. Backend validates API key, counts request, writes to Firebase\n * 4. Frontend subscribes to Firebase for real-time updates\n */\nexport class PindownPubSub extends PubSub {\n private apiKey: string;\n private backendUrl: string;\n private workflowId: string;\n private runId: string;\n private pinId?: string;\n private projectId?: string;\n\n constructor(config: PindownPubSubConfig) {\n super();\n this.apiKey = config.apiKey;\n // Default to production API, allow override for local testing\n this.backendUrl = (config.backendUrl || 'http://api.pindown.ai').replace(/\\/$/, ''); // Remove trailing slash\n this.workflowId = config.workflowId;\n this.runId = config.runId;\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n }\n\n /**\n * Publish event to Pindown.ai backend API\n * \n * Topic format: \"workflow.events.v2.{runId}\"\n * Backend API endpoint: POST /api/workflows/events\n * \n * Backend will:\n * - Validate API key\n * - Count request (for billing/limits)\n * - Write to Firebase Realtime Database\n */\n async publish(topic: string, event: Omit<Event, 'id' | 'createdAt'>): Promise<void> {\n // Parse topic to extract runId\n // Topic format: \"workflow.events.v2.{runId}\"\n const match = topic.match(/^workflow\\.events\\.v2\\.(.+)$/);\n if (!match) {\n return; // Ignore non-workflow topics\n }\n\n const eventData = {\n type: event.type,\n runId: this.runId,\n workflowId: this.workflowId,\n ...event.data,\n timestamp: Date.now(),\n createdAt: new Date().toISOString(),\n };\n\n try {\n // POST to backend API with API key\n const response = await fetch(`${this.backendUrl}/api/workflows/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n runId: this.runId,\n workflowId: this.workflowId,\n pinId: this.pinId,\n projectId: this.projectId,\n event: eventData,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`PindownPubSub: Failed to publish event`, {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n eventType: event.type,\n });\n // Don't throw - publishing failures shouldn't break workflow execution\n }\n } catch (error: any) {\n // Log but don't throw - publishing failures shouldn't break workflow execution\n console.error('PindownPubSub: Error publishing event', {\n error: error.message || String(error),\n eventType: event.type,\n });\n }\n }\n\n /**\n * Subscribe - Not needed on backend, frontend subscribes directly to Firebase\n * This is just for API compatibility with PubSub interface\n */\n async subscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n // Backend doesn't subscribe - frontend does via Firebase listeners\n // This is just for API compatibility with PubSub interface\n }\n\n /**\n * Unsubscribe - No-op on backend\n */\n async unsubscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n // No-op on backend\n }\n\n /**\n * Flush - No-op for Firebase\n */\n async flush(): Promise<void> {\n // No-op\n }\n\n /**\n * Close - Cleanup (no-op for Firebase)\n */\n async close(): Promise<void> {\n // No-op\n }\n}\n","/**\n * PindownRun - Run class with Firebase PubSub integration\n * \n * Extends base Run class and publishes events to Firebase during execution.\n * This is where the magic happens - step updates are published to Firebase\n * so the frontend can subscribe in real-time.\n */\n\nimport type { Mastra } from '@mastra/core/mastra';\nimport { Run } from '@mastra/core/workflows';\nimport type {\n Step,\n ExecutionEngine,\n ExecutionGraph,\n SerializedStepFlowEntry,\n StepWithComponent,\n WorkflowEngineType,\n} from '@mastra/core/workflows';\nimport { PindownPubSub } from './pubsub';\nimport type { PindownEngineType } from './types';\n\nexport class PindownRun<\n TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n >[],\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n> extends Run<PindownEngineType, TSteps, TState, TInput, TOutput> {\n private apiKey: string;\n private backendUrl: string;\n public workflowId: string;\n private pinId?: string;\n private projectId?: string;\n private _pubsub: PindownPubSub | null = null;\n \n // Override pubsub property to satisfy base class type\n // @ts-expect-error - Base class expects PubSub, we use PindownPubSub | null\n public get pubsub(): PindownPubSub {\n if (!this._pubsub) {\n throw new Error('PubSub not initialized. Call initializePubSub() first.');\n }\n return this._pubsub;\n }\n public serializedStepGraph: SerializedStepFlowEntry[];\n #mastra: Mastra | undefined;\n\n constructor(\n params: {\n workflowId: string;\n runId: string;\n resourceId?: string;\n executionEngine: ExecutionEngine;\n executionGraph: ExecutionGraph;\n serializedStepGraph: SerializedStepFlowEntry[];\n mastra?: Mastra;\n retryConfig?: {\n attempts?: number;\n delay?: number;\n };\n cleanup?: () => void;\n workflowSteps: Record<string, StepWithComponent>;\n workflowEngineType: WorkflowEngineType;\n validateInputs?: boolean;\n },\n config: {\n apiKey: string;\n backendUrl: string;\n pinId?: string;\n projectId?: string;\n }\n ) {\n super(params);\n this.apiKey = config.apiKey;\n this.backendUrl = config.backendUrl;\n this.workflowId = params.workflowId;\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n this.serializedStepGraph = params.serializedStepGraph || [];\n this.#mastra = params.mastra;\n }\n\n /**\n * Initialize PubSub for this run\n * Called before workflow execution starts\n */\n private initializePubSub(): void {\n if (!this._pubsub) {\n this._pubsub = new PindownPubSub({\n apiKey: this.apiKey,\n backendUrl: this.backendUrl,\n workflowId: this.workflowId,\n runId: this.runId,\n pinId: this.pinId,\n projectId: this.projectId,\n });\n\n // Attach pubsub to execution engine so it can publish events\n // This is a hook that allows the execution engine to publish step updates\n (this.executionEngine as any).pubsub = this._pubsub;\n }\n }\n\n /**\n * Start workflow execution with Firebase PubSub\n * \n * Overrides base start() to initialize PubSub and publish workflow events\n */\n // @ts-expect-error - Base class has different signature, but runtime works\n async start(inputData: TInput): Promise<any> {\n // Initialize PubSub before starting\n this.initializePubSub();\n\n // Publish workflow started event with step graph\n // This allows the frontend to visualize the workflow structure before execution\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.started',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n inputData,\n // Send the step graph so frontend can visualize the workflow structure\n stepGraph: this.serializedStepGraph,\n },\n } as any);\n }\n\n try {\n // Execute workflow (base class handles step execution)\n // The execution engine will publish step events via pubsub\n const result = await super.start({ inputData } as any);\n\n // Publish workflow completed event\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.completed',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n output: result,\n },\n } as any);\n }\n\n return result;\n } catch (error: any) {\n // Publish workflow failed event\n if (this._pubsub) {\n await this._pubsub.publish(`workflow.events.v2.${this.runId}`, {\n type: 'workflow.failed',\n runId: this.runId,\n data: {\n workflowId: this.workflowId,\n runId: this.runId,\n error: error.message || String(error),\n },\n } as any);\n }\n\n throw error;\n }\n }\n\n /**\n * Get PubSub instance (for testing/debugging)\n */\n getPubSub(): PindownPubSub | null {\n return this._pubsub;\n }\n}\n","/**\n * @mastra/pindown\n * \n * Mastra workflow integration for Pindown.ai with Firebase Realtime Database PubSub\n * \n * Provides:\n * - PindownPubSub: Firebase-based PubSub implementation\n * - PindownWorkflow: Workflow class with Firebase integration\n * - PindownRun: Run class that publishes events to Firebase\n * - init(): Helper function to create workflow and step factories\n */\n\nexport * from './pubsub';\nexport * from './workflow';\nexport * from './run';\nexport * from './execution-engine';\nexport * from './types';\nexport { init } from './init';\n","/**\n * PindownExecutionEngine - Execution engine with Firebase PubSub integration\n * \n * Extends default execution engine and hooks into step execution\n * to publish events to Firebase via PubSub.\n * \n * This is where step.started, step.completed, and step.failed events\n * are published to Firebase.\n */\n\nimport { DefaultExecutionEngine } from '@mastra/core/workflows';\nimport type {\n ExecutionEngineOptions,\n Step,\n StepResult,\n} from '@mastra/core/workflows';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { PindownPubSub } from './pubsub';\nimport type { PindownEngineType } from './types';\n\nexport class PindownExecutionEngine extends DefaultExecutionEngine {\n public pubsub?: PindownPubSub;\n\n constructor(mastra: Mastra, options: ExecutionEngineOptions) {\n super({ mastra, options });\n }\n\n /**\n * Override executeStep to publish events to Firebase\n * \n * This hooks into step execution to publish:\n * - step.started when step begins\n * - step.completed when step succeeds\n * - step.failed when step fails\n */\n async executeStep<T>(\n paramsOrStepId: any,\n step?: Step<any, any, any, any, any, any, PindownEngineType>,\n context?: any\n ): Promise<any> {\n // Handle both old API (stepId, step, context) and new API (params object)\n let stepId: string;\n let stepToExecute: Step<any, any, any, any, any, any, PindownEngineType>;\n let executionContext: any;\n let runId: string;\n\n if (typeof paramsOrStepId === 'string') {\n // Old API: executeStep(stepId, step, context)\n stepId = paramsOrStepId;\n stepToExecute = step!;\n executionContext = context!;\n runId = executionContext?.runId || executionContext?.params?.runId || '';\n } else {\n // New API: executeStep({ stepId, step, context })\n const params = paramsOrStepId;\n stepId = params.stepId;\n stepToExecute = params.step;\n executionContext = params.context || params;\n runId = executionContext?.runId || executionContext?.params?.runId || '';\n }\n\n // Publish step started event\n if (this.pubsub && runId) {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.started',\n runId,\n data: {\n stepId,\n inputData: executionContext?.inputData,\n },\n } as any);\n }\n\n try {\n // Execute step (base class handles the actual execution)\n const result = typeof paramsOrStepId === 'string'\n ? await super.executeStep({ stepId, step: stepToExecute, context: executionContext } as any)\n : await super.executeStep(paramsOrStepId);\n\n // Publish step completed event\n if (this.pubsub && runId && (result as any)?.status === 'completed') {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.completed',\n runId,\n data: {\n stepId,\n output: (result as any)?.output,\n },\n } as any);\n }\n\n return result;\n } catch (error: any) {\n // Publish step failed event\n if (this.pubsub && runId) {\n await this.pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'step.failed',\n runId,\n data: {\n stepId,\n error: error.message || String(error),\n },\n } as any);\n }\n\n throw error;\n }\n }\n}\n","import type { Mastra } from '@mastra/core/mastra';\nimport { Workflow } from '@mastra/core/workflows';\nimport type { Step } from '@mastra/core/workflows';\nimport type { PindownInitConfig } from './types';\nimport type { PindownEngineType } from './types';\nimport { PindownExecutionEngine } from './execution-engine';\n\n/**\n * PindownWorkflow - Workflow class with Pindown.ai backend API integration\n * \n * Extends base Workflow class and adds HTTP-based PubSub that publishes\n * to Pindown.ai backend API (with API key validation and request counting).\n */\nexport class PindownWorkflow<\n TSteps extends Step<string, any, any, any, any, any, PindownEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n >[],\n TWorkflowId extends string = string,\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n TPrevSchema = TInput,\n> extends Workflow<PindownEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrevSchema> {\n #mastra: Mastra | undefined;\n private apiKey: string;\n private backendUrl: string;\n private pinId?: string;\n private projectId?: string;\n\n constructor(\n params: {\n id: TWorkflowId;\n inputSchema: any;\n outputSchema: any;\n stateSchema?: any;\n steps?: TSteps;\n description?: string;\n options?: {\n validateInputs?: boolean;\n };\n },\n config: PindownInitConfig\n ) {\n super(params);\n // Set engineType on the base class (it's a protected property)\n (this as any).engineType = 'pindown';\n this.apiKey = config.apiKey;\n // Default to production API, allow override for local testing\n this.backendUrl = config.backendUrl || 'http://api.pindown.ai';\n this.pinId = config.pinId;\n this.projectId = config.projectId;\n }\n\n __registerMastra(mastra: Mastra) {\n super.__registerMastra(mastra);\n this.#mastra = mastra;\n \n // Replace execution engine with PindownExecutionEngine\n // This ensures step events are published to Firebase\n const baseExecutionEngine = (this as any).executionEngine;\n (this as any).executionEngine = new PindownExecutionEngine(mastra, {\n validateInputs: (this as any).options?.validateInputs ?? true,\n shouldPersistSnapshot: () => false,\n });\n \n // Copy any necessary state from base engine\n // Register mastra with new engine\n (this as any).executionEngine.__registerMastra(mastra);\n }\n\n /**\n * Get API key (for debugging/testing)\n */\n getApiKey(): string {\n return this.apiKey;\n }\n\n /**\n * Get backend URL\n */\n getBackendUrl(): string {\n return this.backendUrl;\n }\n\n /**\n * Get pin ID\n */\n getPinId(): string | undefined {\n return this.pinId;\n }\n\n /**\n * Get project ID\n */\n getProjectId(): string | undefined {\n return this.projectId;\n }\n\n /**\n * Override createRun to pass config to PindownRun\n */\n // @ts-expect-error - Type mismatch with base class generics, but runtime works correctly\n async createRun(options?: {\n runId?: string;\n resourceId?: string;\n }) {\n // Generate runId if not provided\n let runIdToUse = options?.runId;\n if (!runIdToUse) {\n // Use crypto.randomUUID if available (Node.js 16+), otherwise fallback\n try {\n const crypto = await import('node:crypto');\n runIdToUse = crypto.randomUUID();\n } catch {\n // Fallback for environments without node:crypto\n runIdToUse = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;\n }\n }\n \n const { PindownRun } = await import('./run');\n const pindownRun = new PindownRun(\n {\n workflowId: (this as any).id, // Access id from base class\n runId: runIdToUse,\n resourceId: options?.resourceId,\n executionEngine: (this as any).executionEngine, // Access from base class\n executionGraph: (this as any).executionGraph,\n serializedStepGraph: (this as any).serializedStepGraph,\n mastra: this.#mastra,\n workflowSteps: (this as any).steps || (this as any).workflowSteps,\n workflowEngineType: (this as any).engineType, // Access from base class\n validateInputs: (this as any).options?.validateInputs, // Access from base class\n },\n {\n apiKey: this.apiKey,\n backendUrl: this.backendUrl,\n pinId: this.pinId,\n projectId: this.projectId,\n }\n );\n\n // Store run in workflow's runs map (if it exists)\n if ((this as any).runs) {\n (this as any).runs.set(runIdToUse, pindownRun);\n }\n\n return pindownRun;\n }\n}\n","/**\n * createStep - Factory function to create workflow steps\n * \n * For now, this is a simple pass-through that creates steps compatible with Pindown engine.\n * In the future, this can be extended to add Pindown-specific step features.\n */\n\nimport type { StepParams, Step } from '@mastra/core/workflows';\nimport type { PindownEngineType } from './types';\nimport type { ZodTypeAny } from 'zod';\n\n/**\n * Create a step from explicit params\n */\nexport function createStep<\n TStepId extends string,\n TStateSchema extends ZodTypeAny | undefined = any,\n TInputSchema extends ZodTypeAny | undefined = any,\n TOutputSchema extends ZodTypeAny | undefined = any,\n TResumeSchema extends ZodTypeAny | undefined = undefined,\n TSuspendSchema extends ZodTypeAny | undefined = undefined,\n>(\n // @ts-expect-error - Type constraints don't match exactly, but runtime works\n params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>\n): Step<\n TStepId,\n any,\n any,\n any,\n any,\n any,\n PindownEngineType\n> {\n return {\n id: params.id,\n description: params.description,\n inputSchema: params.inputSchema,\n stateSchema: params.stateSchema,\n outputSchema: params.outputSchema,\n resumeSchema: params.resumeSchema,\n suspendSchema: params.suspendSchema,\n scorers: params.scorers,\n retries: params.retries,\n execute: params.execute.bind(params),\n } as Step<any, any, any, any, any, any, PindownEngineType>;\n}\n","import type { Step } from '@mastra/core/workflows';\nimport { PindownWorkflow } from './workflow';\nimport { createStep } from './step';\nimport type { PindownInitConfig } from './types';\n\n/**\n * Initialize Pindown workflow helpers\n * \n * Similar to @mastra/inngest's init() function\n * Returns createWorkflow and createStep factories\n * \n * Users provide API key and backend URL.\n * The package will publish events to your backend API,\n * which validates API keys, counts requests, and writes to Firebase.\n * \n * @param config - Pindown configuration with API key and backend URL\n * @returns Object with createWorkflow and createStep functions\n * \n * @example\n * ```typescript\n * import { init } from '@mastra/pindown';\n * \n * // Production (defaults to http://api.pindown.ai)\n * const { createWorkflow, createStep } = init({\n * apiKey: 'pk_live_...',\n * pinId: 'pin-abc123' // or projectId: 'project-xyz'\n * });\n * \n * // Local testing\n * const { createWorkflow, createStep } = init({\n * apiKey: 'pk_test_...',\n * backendUrl: 'http://localhost:8000',\n * pinId: 'pin-abc123'\n * });\n * ```\n */\nexport function init(config: PindownInitConfig) {\n return {\n /**\n * Create a Pindown workflow\n */\n createWorkflow<\n TWorkflowId extends string = string,\n TState = any,\n TInput = any,\n TOutput = any,\n TSteps extends Step<string, any, any, any, any, any, 'pindown'>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n 'pindown'\n >[]\n >(params: {\n id: TWorkflowId;\n inputSchema: any;\n outputSchema: any;\n stateSchema?: any;\n steps?: TSteps;\n description?: string;\n options?: {\n validateInputs?: boolean;\n };\n }) {\n return new PindownWorkflow(params, config);\n },\n\n /**\n * Create a step (delegates to createStep)\n */\n createStep,\n };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pindownai/mastra-pindown",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mastra workflow integration for Pindown.ai with Firebase Realtime Database PubSub",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"dev": "tsup --watch",
|
|
19
|
+
"clean": "rm -rf dist",
|
|
20
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mastra",
|
|
24
|
+
"workflow",
|
|
25
|
+
"firebase",
|
|
26
|
+
"realtime",
|
|
27
|
+
"pubsub",
|
|
28
|
+
"pindown",
|
|
29
|
+
"typescript"
|
|
30
|
+
],
|
|
31
|
+
"author": "Pindown.ai",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@mastra/core": "^1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.0.0",
|
|
38
|
+
"tsup": "^8.0.0",
|
|
39
|
+
"typescript": "^5.3.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22.0.0"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
]
|
|
49
|
+
}
|