@positronic/cloudflare 0.0.20 → 0.0.22

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/dist/src/api.js CHANGED
@@ -1591,7 +1591,16 @@ app.post('/webhooks/:slug', function(context) {
1591
1591
  ];
1592
1592
  case 2:
1593
1593
  result = _state.sent();
1594
- // Check if there's a brain waiting for this webhook
1594
+ // Handle verification challenge (for Slack, Stripe, GitHub, Discord)
1595
+ if (result.type === 'verification') {
1596
+ return [
1597
+ 2,
1598
+ context.json({
1599
+ challenge: result.challenge
1600
+ })
1601
+ ];
1602
+ }
1603
+ // Normal webhook processing - check if there's a brain waiting
1595
1604
  monitorId = context.env.MONITOR_DO.idFromName('singleton');
1596
1605
  monitorStub = context.env.MONITOR_DO.get(monitorId);
1597
1606
  return [
@@ -1651,4 +1660,500 @@ app.post('/webhooks/:slug', function(context) {
1651
1660
  });
1652
1661
  })();
1653
1662
  });
1663
+ // Create a new page
1664
+ app.post('/pages', function(context) {
1665
+ return _async_to_generator(function() {
1666
+ var body, slug, html, brainRunId, _body_persist, persist, ttl, bucket, key, createdAt, metadata, monitorId, monitorStub, url, pageUrl, error;
1667
+ return _ts_generator(this, function(_state) {
1668
+ switch(_state.label){
1669
+ case 0:
1670
+ _state.trys.push([
1671
+ 0,
1672
+ 4,
1673
+ ,
1674
+ 5
1675
+ ]);
1676
+ return [
1677
+ 4,
1678
+ context.req.json()
1679
+ ];
1680
+ case 1:
1681
+ body = _state.sent();
1682
+ slug = body.slug, html = body.html, brainRunId = body.brainRunId, _body_persist = body.persist, persist = _body_persist === void 0 ? false : _body_persist, ttl = body.ttl;
1683
+ if (!slug) {
1684
+ return [
1685
+ 2,
1686
+ context.json({
1687
+ error: 'Missing required field "slug"'
1688
+ }, 400)
1689
+ ];
1690
+ }
1691
+ if (!html) {
1692
+ return [
1693
+ 2,
1694
+ context.json({
1695
+ error: 'Missing required field "html"'
1696
+ }, 400)
1697
+ ];
1698
+ }
1699
+ if (!brainRunId) {
1700
+ return [
1701
+ 2,
1702
+ context.json({
1703
+ error: 'Missing required field "brainRunId"'
1704
+ }, 400)
1705
+ ];
1706
+ }
1707
+ // Validate slug format (alphanumeric, hyphens, underscores only)
1708
+ if (!/^[a-zA-Z0-9_-]+$/.test(slug)) {
1709
+ return [
1710
+ 2,
1711
+ context.json({
1712
+ error: 'Slug must contain only alphanumeric characters, hyphens, and underscores'
1713
+ }, 400)
1714
+ ];
1715
+ }
1716
+ bucket = context.env.RESOURCES_BUCKET;
1717
+ key = "pages/".concat(slug, ".html");
1718
+ createdAt = new Date().toISOString();
1719
+ // Store HTML with metadata
1720
+ metadata = _object_spread({
1721
+ slug: slug,
1722
+ brainRunId: brainRunId,
1723
+ persist: persist === true,
1724
+ createdAt: createdAt
1725
+ }, ttl !== undefined && {
1726
+ ttl: Number(ttl)
1727
+ });
1728
+ return [
1729
+ 4,
1730
+ bucket.put(key, html, {
1731
+ httpMetadata: {
1732
+ contentType: 'text/html; charset=utf-8'
1733
+ },
1734
+ customMetadata: _object_spread({
1735
+ slug: slug,
1736
+ brainRunId: brainRunId,
1737
+ persist: persist === true ? 'true' : 'false',
1738
+ createdAt: createdAt
1739
+ }, ttl !== undefined && {
1740
+ ttl: String(ttl)
1741
+ })
1742
+ })
1743
+ ];
1744
+ case 2:
1745
+ _state.sent();
1746
+ // Register the page with MonitorDO for cleanup tracking
1747
+ monitorId = context.env.MONITOR_DO.idFromName('singleton');
1748
+ monitorStub = context.env.MONITOR_DO.get(monitorId);
1749
+ return [
1750
+ 4,
1751
+ monitorStub.registerPage(slug, brainRunId, persist === true)
1752
+ ];
1753
+ case 3:
1754
+ _state.sent();
1755
+ // Build the public URL for this page
1756
+ url = new URL(context.req.url);
1757
+ pageUrl = "".concat(url.protocol, "//").concat(url.host, "/pages/").concat(slug);
1758
+ return [
1759
+ 2,
1760
+ context.json(_object_spread_props(_object_spread({
1761
+ slug: slug,
1762
+ url: pageUrl,
1763
+ brainRunId: brainRunId,
1764
+ persist: persist === true
1765
+ }, ttl !== undefined && {
1766
+ ttl: Number(ttl)
1767
+ }), {
1768
+ createdAt: createdAt
1769
+ }), 201)
1770
+ ];
1771
+ case 4:
1772
+ error = _state.sent();
1773
+ console.error('Error creating page:', error);
1774
+ return [
1775
+ 2,
1776
+ context.json({
1777
+ error: "Failed to create page: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
1778
+ }, 500)
1779
+ ];
1780
+ case 5:
1781
+ return [
1782
+ 2
1783
+ ];
1784
+ }
1785
+ });
1786
+ })();
1787
+ });
1788
+ // List all pages
1789
+ app.get('/pages', function(context) {
1790
+ return _async_to_generator(function() {
1791
+ var bucket, listed, pages, validPages, error;
1792
+ return _ts_generator(this, function(_state) {
1793
+ switch(_state.label){
1794
+ case 0:
1795
+ bucket = context.env.RESOURCES_BUCKET;
1796
+ _state.label = 1;
1797
+ case 1:
1798
+ _state.trys.push([
1799
+ 1,
1800
+ 4,
1801
+ ,
1802
+ 5
1803
+ ]);
1804
+ return [
1805
+ 4,
1806
+ bucket.list({
1807
+ prefix: 'pages/'
1808
+ })
1809
+ ];
1810
+ case 2:
1811
+ listed = _state.sent();
1812
+ return [
1813
+ 4,
1814
+ Promise.all(listed.objects.map(function(object) {
1815
+ return _async_to_generator(function() {
1816
+ var r2Object, metadata, slug, url, pageUrl;
1817
+ return _ts_generator(this, function(_state) {
1818
+ switch(_state.label){
1819
+ case 0:
1820
+ return [
1821
+ 4,
1822
+ bucket.head(object.key)
1823
+ ];
1824
+ case 1:
1825
+ r2Object = _state.sent();
1826
+ if (!r2Object) {
1827
+ return [
1828
+ 2,
1829
+ null
1830
+ ];
1831
+ }
1832
+ metadata = r2Object.customMetadata || {};
1833
+ slug = metadata.slug || object.key.replace('pages/', '').replace('.html', '');
1834
+ // Build the public URL
1835
+ url = new URL(context.req.url);
1836
+ pageUrl = "".concat(url.protocol, "//").concat(url.host, "/pages/").concat(slug);
1837
+ return [
1838
+ 2,
1839
+ _object_spread_props(_object_spread({
1840
+ slug: slug,
1841
+ url: pageUrl,
1842
+ brainRunId: metadata.brainRunId || '',
1843
+ persist: metadata.persist === 'true'
1844
+ }, metadata.ttl && {
1845
+ ttl: Number(metadata.ttl)
1846
+ }), {
1847
+ createdAt: metadata.createdAt || object.uploaded.toISOString(),
1848
+ size: object.size
1849
+ })
1850
+ ];
1851
+ }
1852
+ });
1853
+ })();
1854
+ }))
1855
+ ];
1856
+ case 3:
1857
+ pages = _state.sent();
1858
+ // Filter out any null entries
1859
+ validPages = pages.filter(function(page) {
1860
+ return page !== null;
1861
+ });
1862
+ return [
1863
+ 2,
1864
+ context.json({
1865
+ pages: validPages,
1866
+ count: validPages.length
1867
+ })
1868
+ ];
1869
+ case 4:
1870
+ error = _state.sent();
1871
+ console.error('Error listing pages:', error);
1872
+ return [
1873
+ 2,
1874
+ context.json({
1875
+ error: "Failed to list pages: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
1876
+ }, 500)
1877
+ ];
1878
+ case 5:
1879
+ return [
1880
+ 2
1881
+ ];
1882
+ }
1883
+ });
1884
+ })();
1885
+ });
1886
+ // Get page metadata (without content)
1887
+ app.get('/pages/:slug/meta', function(context) {
1888
+ return _async_to_generator(function() {
1889
+ var slug, bucket, key, r2Object, metadata, error;
1890
+ return _ts_generator(this, function(_state) {
1891
+ switch(_state.label){
1892
+ case 0:
1893
+ slug = context.req.param('slug');
1894
+ bucket = context.env.RESOURCES_BUCKET;
1895
+ key = "pages/".concat(slug, ".html");
1896
+ _state.label = 1;
1897
+ case 1:
1898
+ _state.trys.push([
1899
+ 1,
1900
+ 3,
1901
+ ,
1902
+ 4
1903
+ ]);
1904
+ return [
1905
+ 4,
1906
+ bucket.head(key)
1907
+ ];
1908
+ case 2:
1909
+ r2Object = _state.sent();
1910
+ if (!r2Object) {
1911
+ return [
1912
+ 2,
1913
+ context.json({
1914
+ error: 'Page not found'
1915
+ }, 404)
1916
+ ];
1917
+ }
1918
+ metadata = r2Object.customMetadata || {};
1919
+ return [
1920
+ 2,
1921
+ context.json(_object_spread_props(_object_spread({
1922
+ slug: metadata.slug || slug,
1923
+ brainRunId: metadata.brainRunId || '',
1924
+ persist: metadata.persist === 'true'
1925
+ }, metadata.ttl && {
1926
+ ttl: Number(metadata.ttl)
1927
+ }), {
1928
+ createdAt: metadata.createdAt || r2Object.uploaded.toISOString(),
1929
+ size: r2Object.size
1930
+ }))
1931
+ ];
1932
+ case 3:
1933
+ error = _state.sent();
1934
+ console.error("Error getting page metadata for ".concat(slug, ":"), error);
1935
+ return [
1936
+ 2,
1937
+ context.json({
1938
+ error: "Failed to get page metadata: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
1939
+ }, 500)
1940
+ ];
1941
+ case 4:
1942
+ return [
1943
+ 2
1944
+ ];
1945
+ }
1946
+ });
1947
+ })();
1948
+ });
1949
+ // Get page HTML content
1950
+ app.get('/pages/:slug', function(context) {
1951
+ return _async_to_generator(function() {
1952
+ var slug, bucket, key, r2Object, html, error;
1953
+ return _ts_generator(this, function(_state) {
1954
+ switch(_state.label){
1955
+ case 0:
1956
+ slug = context.req.param('slug');
1957
+ bucket = context.env.RESOURCES_BUCKET;
1958
+ key = "pages/".concat(slug, ".html");
1959
+ _state.label = 1;
1960
+ case 1:
1961
+ _state.trys.push([
1962
+ 1,
1963
+ 4,
1964
+ ,
1965
+ 5
1966
+ ]);
1967
+ return [
1968
+ 4,
1969
+ bucket.get(key)
1970
+ ];
1971
+ case 2:
1972
+ r2Object = _state.sent();
1973
+ if (!r2Object) {
1974
+ return [
1975
+ 2,
1976
+ context.json({
1977
+ error: 'Page not found'
1978
+ }, 404)
1979
+ ];
1980
+ }
1981
+ return [
1982
+ 4,
1983
+ r2Object.text()
1984
+ ];
1985
+ case 3:
1986
+ html = _state.sent();
1987
+ return [
1988
+ 2,
1989
+ new Response(html, {
1990
+ status: 200,
1991
+ headers: {
1992
+ 'Content-Type': 'text/html; charset=utf-8'
1993
+ }
1994
+ })
1995
+ ];
1996
+ case 4:
1997
+ error = _state.sent();
1998
+ console.error("Error getting page ".concat(slug, ":"), error);
1999
+ return [
2000
+ 2,
2001
+ context.json({
2002
+ error: "Failed to get page: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
2003
+ }, 500)
2004
+ ];
2005
+ case 5:
2006
+ return [
2007
+ 2
2008
+ ];
2009
+ }
2010
+ });
2011
+ })();
2012
+ });
2013
+ // Update page HTML content
2014
+ app.put('/pages/:slug', function(context) {
2015
+ return _async_to_generator(function() {
2016
+ var slug, bucket, key, existingObject, body, html, existingMetadata, url, pageUrl, error;
2017
+ return _ts_generator(this, function(_state) {
2018
+ switch(_state.label){
2019
+ case 0:
2020
+ slug = context.req.param('slug');
2021
+ bucket = context.env.RESOURCES_BUCKET;
2022
+ key = "pages/".concat(slug, ".html");
2023
+ _state.label = 1;
2024
+ case 1:
2025
+ _state.trys.push([
2026
+ 1,
2027
+ 5,
2028
+ ,
2029
+ 6
2030
+ ]);
2031
+ return [
2032
+ 4,
2033
+ bucket.head(key)
2034
+ ];
2035
+ case 2:
2036
+ existingObject = _state.sent();
2037
+ if (!existingObject) {
2038
+ return [
2039
+ 2,
2040
+ context.json({
2041
+ error: 'Page not found'
2042
+ }, 404)
2043
+ ];
2044
+ }
2045
+ return [
2046
+ 4,
2047
+ context.req.json()
2048
+ ];
2049
+ case 3:
2050
+ body = _state.sent();
2051
+ html = body.html;
2052
+ if (!html) {
2053
+ return [
2054
+ 2,
2055
+ context.json({
2056
+ error: 'Missing required field "html"'
2057
+ }, 400)
2058
+ ];
2059
+ }
2060
+ // Preserve existing metadata
2061
+ existingMetadata = existingObject.customMetadata || {};
2062
+ // Update with new HTML, preserving metadata
2063
+ return [
2064
+ 4,
2065
+ bucket.put(key, html, {
2066
+ httpMetadata: {
2067
+ contentType: 'text/html; charset=utf-8'
2068
+ },
2069
+ customMetadata: existingMetadata
2070
+ })
2071
+ ];
2072
+ case 4:
2073
+ _state.sent();
2074
+ // Build the public URL
2075
+ url = new URL(context.req.url);
2076
+ pageUrl = "".concat(url.protocol, "//").concat(url.host, "/pages/").concat(slug);
2077
+ return [
2078
+ 2,
2079
+ context.json({
2080
+ slug: slug,
2081
+ url: pageUrl,
2082
+ updatedAt: new Date().toISOString()
2083
+ })
2084
+ ];
2085
+ case 5:
2086
+ error = _state.sent();
2087
+ console.error("Error updating page ".concat(slug, ":"), error);
2088
+ return [
2089
+ 2,
2090
+ context.json({
2091
+ error: "Failed to update page: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
2092
+ }, 500)
2093
+ ];
2094
+ case 6:
2095
+ return [
2096
+ 2
2097
+ ];
2098
+ }
2099
+ });
2100
+ })();
2101
+ });
2102
+ // Delete a page
2103
+ app.delete('/pages/:slug', function(context) {
2104
+ return _async_to_generator(function() {
2105
+ var slug, bucket, key, monitorId, monitorStub, error;
2106
+ return _ts_generator(this, function(_state) {
2107
+ switch(_state.label){
2108
+ case 0:
2109
+ slug = context.req.param('slug');
2110
+ bucket = context.env.RESOURCES_BUCKET;
2111
+ key = "pages/".concat(slug, ".html");
2112
+ _state.label = 1;
2113
+ case 1:
2114
+ _state.trys.push([
2115
+ 1,
2116
+ 4,
2117
+ ,
2118
+ 5
2119
+ ]);
2120
+ // R2 delete is idempotent - no error if object doesn't exist
2121
+ return [
2122
+ 4,
2123
+ bucket.delete(key)
2124
+ ];
2125
+ case 2:
2126
+ _state.sent();
2127
+ // Also remove from MonitorDO tracking
2128
+ monitorId = context.env.MONITOR_DO.idFromName('singleton');
2129
+ monitorStub = context.env.MONITOR_DO.get(monitorId);
2130
+ return [
2131
+ 4,
2132
+ monitorStub.unregisterPage(slug)
2133
+ ];
2134
+ case 3:
2135
+ _state.sent();
2136
+ return [
2137
+ 2,
2138
+ new Response(null, {
2139
+ status: 204
2140
+ })
2141
+ ];
2142
+ case 4:
2143
+ error = _state.sent();
2144
+ console.error("Error deleting page ".concat(slug, ":"), error);
2145
+ return [
2146
+ 2,
2147
+ context.json({
2148
+ error: "Failed to delete page: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
2149
+ }, 500)
2150
+ ];
2151
+ case 5:
2152
+ return [
2153
+ 2
2154
+ ];
2155
+ }
2156
+ });
2157
+ })();
2158
+ });
1654
2159
  export default app;
@@ -247,6 +247,7 @@ import { STATUS, BRAIN_EVENTS } from '@positronic/core';
247
247
  import { DurableObject } from 'cloudflare:workers';
248
248
  import { BrainRunSQLiteAdapter } from './sqlite-adapter.js';
249
249
  import { WebhookAdapter } from './webhook-adapter.js';
250
+ import { PageAdapter } from './page-adapter.js';
250
251
  import { CloudflareR2Loader } from './r2-loader.js';
251
252
  import { createResources } from '@positronic/core';
252
253
  var manifest = null;
@@ -569,7 +570,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
569
570
  key: "start",
570
571
  value: function start(brainTitle, brainRunId, initialData) {
571
572
  return _async_to_generator(function() {
572
- var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, r2Resources, runnerWithResources, options, initialState;
573
+ var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, pageAdapter, r2Resources, runnerWithResources, options, initialState;
573
574
  return _ts_generator(this, function(_state) {
574
575
  switch(_state.label){
575
576
  case 0:
@@ -599,6 +600,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
599
600
  monitorAdapter = new MonitorAdapter(monitorDOStub);
600
601
  scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
601
602
  webhookAdapter = new WebhookAdapter(monitorDOStub);
603
+ pageAdapter = new PageAdapter(monitorDOStub, this.env.RESOURCES_BUCKET);
602
604
  if (!brainRunner) {
603
605
  throw new Error('BrainRunner not initialized');
604
606
  }
@@ -624,7 +626,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
624
626
  eventStreamAdapter,
625
627
  monitorAdapter,
626
628
  scheduleAdapter,
627
- webhookAdapter
629
+ webhookAdapter,
630
+ pageAdapter
628
631
  ]).run(brainToRun, _object_spread_props(_object_spread({
629
632
  initialState: initialState,
630
633
  brainRunId: brainRunId
@@ -651,7 +654,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
651
654
  key: "resume",
652
655
  value: function resume(brainRunId, webhookResponse) {
653
656
  return _async_to_generator(function() {
654
- var _this, sql, startEventResult, startEvent, brainTitle, initialState, resolution, brainToRun, eventsResult, initialCompletedSteps, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, r2Resources, runnerWithResources;
657
+ var _this, sql, startEventResult, startEvent, brainTitle, initialState, resolution, brainToRun, eventsResult, initialCompletedSteps, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, pageAdapter, r2Resources, runnerWithResources;
655
658
  return _ts_generator(this, function(_state) {
656
659
  switch(_state.label){
657
660
  case 0:
@@ -702,6 +705,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
702
705
  monitorAdapter = new MonitorAdapter(monitorDOStub);
703
706
  scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
704
707
  webhookAdapter = new WebhookAdapter(monitorDOStub);
708
+ pageAdapter = new PageAdapter(monitorDOStub, this.env.RESOURCES_BUCKET);
705
709
  if (!brainRunner) {
706
710
  throw new Error('BrainRunner not initialized');
707
711
  }
@@ -722,7 +726,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
722
726
  eventStreamAdapter,
723
727
  monitorAdapter,
724
728
  scheduleAdapter,
725
- webhookAdapter
729
+ webhookAdapter,
730
+ pageAdapter
726
731
  ]).run(brainToRun, {
727
732
  initialState: initialState,
728
733
  initialCompletedSteps: initialCompletedSteps,
@@ -218,7 +218,7 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
218
218
  ]), _define_property(_this, "storage", void 0), _define_property(_this, "eventStreamHandler", new EventStreamHandler());
219
219
  _this.storage = state.storage.sql;
220
220
  // Update table schema and indexes
221
- _this.storage.exec("\n CREATE TABLE IF NOT EXISTS brain_runs (\n run_id TEXT PRIMARY KEY,\n brain_title TEXT NOT NULL, -- Renamed column\n brain_description TEXT, -- Renamed column\n type TEXT NOT NULL,\n status TEXT NOT NULL,\n options TEXT,\n error TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_brain_status -- Renamed index\n ON brain_runs(brain_title, status);\n\n CREATE INDEX IF NOT EXISTS idx_brain_time -- Renamed index\n ON brain_runs(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS webhook_registrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL,\n identifier TEXT NOT NULL,\n brain_run_id TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_webhook_lookup\n ON webhook_registrations(slug, identifier);\n\n CREATE INDEX IF NOT EXISTS idx_webhook_brain_run\n ON webhook_registrations(brain_run_id);\n ");
221
+ _this.storage.exec("\n CREATE TABLE IF NOT EXISTS brain_runs (\n run_id TEXT PRIMARY KEY,\n brain_title TEXT NOT NULL, -- Renamed column\n brain_description TEXT, -- Renamed column\n type TEXT NOT NULL,\n status TEXT NOT NULL,\n options TEXT,\n error TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_brain_status -- Renamed index\n ON brain_runs(brain_title, status);\n\n CREATE INDEX IF NOT EXISTS idx_brain_time -- Renamed index\n ON brain_runs(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS webhook_registrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL,\n identifier TEXT NOT NULL,\n brain_run_id TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_webhook_lookup\n ON webhook_registrations(slug, identifier);\n\n CREATE INDEX IF NOT EXISTS idx_webhook_brain_run\n ON webhook_registrations(brain_run_id);\n\n CREATE TABLE IF NOT EXISTS page_registrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL UNIQUE,\n brain_run_id TEXT NOT NULL,\n persist INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_page_brain_run\n ON page_registrations(brain_run_id);\n\n CREATE INDEX IF NOT EXISTS idx_page_persist\n ON page_registrations(persist);\n ");
222
222
  return _this;
223
223
  }
224
224
  _create_class(MonitorDO, [
@@ -232,9 +232,11 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
232
232
  var error = event.type === BRAIN_EVENTS.ERROR ? JSON.stringify(event.error) : null;
233
233
  // Update SQL insert/update with new column names, read from existing event fields
234
234
  this.storage.exec("\n INSERT INTO brain_runs (\n run_id, brain_title, brain_description, type, status,\n options, error, created_at, started_at, completed_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(run_id) DO UPDATE SET\n type = excluded.type,\n status = excluded.status,\n error = excluded.error,\n completed_at = excluded.completed_at\n ", event.brainRunId, event.brainTitle, event.brainDescription || null, event.type, event.status, JSON.stringify(event.options || {}), error, currentTime, startTime, completeTime);
235
- // Clean up webhook registrations when brain terminates
235
+ // Clean up registrations when brain terminates
236
236
  if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR || event.type === BRAIN_EVENTS.CANCELLED) {
237
237
  this.clearWebhookRegistrations(event.brainRunId);
238
+ // Note: Non-persistent page cleanup is handled by PageAdapter which has access to R2
239
+ // We just track pages here, actual R2 deletion happens in the adapter
238
240
  }
239
241
  this.broadcastRunningBrains();
240
242
  }
@@ -395,6 +397,44 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
395
397
  value: function clearWebhookRegistrations(brainRunId) {
396
398
  this.storage.exec("\n DELETE FROM webhook_registrations\n WHERE brain_run_id = ?\n ", brainRunId);
397
399
  }
400
+ },
401
+ {
402
+ /**
403
+ * Register a page for tracking
404
+ * Called when a page is created via the API
405
+ */ key: "registerPage",
406
+ value: function registerPage(slug, brainRunId, persist) {
407
+ this.storage.exec("\n INSERT INTO page_registrations (slug, brain_run_id, persist, created_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(slug) DO UPDATE SET\n brain_run_id = excluded.brain_run_id,\n persist = excluded.persist\n ", slug, brainRunId, persist ? 1 : 0, Date.now());
408
+ }
409
+ },
410
+ {
411
+ /**
412
+ * Unregister a page (when deleted via API)
413
+ */ key: "unregisterPage",
414
+ value: function unregisterPage(slug) {
415
+ this.storage.exec("\n DELETE FROM page_registrations\n WHERE slug = ?\n ", slug);
416
+ }
417
+ },
418
+ {
419
+ /**
420
+ * Get all non-persistent page slugs for a brain run
421
+ * Used by PageAdapter to clean up pages when brain terminates
422
+ */ key: "getNonPersistentPagesForRun",
423
+ value: function getNonPersistentPagesForRun(brainRunId) {
424
+ var results = this.storage.exec("\n SELECT slug\n FROM page_registrations\n WHERE brain_run_id = ? AND persist = 0\n ", brainRunId).toArray();
425
+ return results.map(function(r) {
426
+ return r.slug;
427
+ });
428
+ }
429
+ },
430
+ {
431
+ /**
432
+ * Clear all page registrations for a brain run
433
+ * Called after pages are cleaned up
434
+ */ key: "clearPageRegistrations",
435
+ value: function clearPageRegistrations(brainRunId) {
436
+ this.storage.exec("\n DELETE FROM page_registrations\n WHERE brain_run_id = ? AND persist = 0\n ", brainRunId);
437
+ }
398
438
  }
399
439
  ]);
400
440
  return MonitorDO;
@@ -0,0 +1,282 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _class_call_check(instance, Constructor) {
31
+ if (!(instance instanceof Constructor)) {
32
+ throw new TypeError("Cannot call a class as a function");
33
+ }
34
+ }
35
+ function _defineProperties(target, props) {
36
+ for(var i = 0; i < props.length; i++){
37
+ var descriptor = props[i];
38
+ descriptor.enumerable = descriptor.enumerable || false;
39
+ descriptor.configurable = true;
40
+ if ("value" in descriptor) descriptor.writable = true;
41
+ Object.defineProperty(target, descriptor.key, descriptor);
42
+ }
43
+ }
44
+ function _create_class(Constructor, protoProps, staticProps) {
45
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
46
+ if (staticProps) _defineProperties(Constructor, staticProps);
47
+ return Constructor;
48
+ }
49
+ function _define_property(obj, key, value) {
50
+ if (key in obj) {
51
+ Object.defineProperty(obj, key, {
52
+ value: value,
53
+ enumerable: true,
54
+ configurable: true,
55
+ writable: true
56
+ });
57
+ } else {
58
+ obj[key] = value;
59
+ }
60
+ return obj;
61
+ }
62
+ function _ts_generator(thisArg, body) {
63
+ var f, y, t, _ = {
64
+ label: 0,
65
+ sent: function() {
66
+ if (t[0] & 1) throw t[1];
67
+ return t[1];
68
+ },
69
+ trys: [],
70
+ ops: []
71
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
72
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
73
+ return this;
74
+ }), g;
75
+ function verb(n) {
76
+ return function(v) {
77
+ return step([
78
+ n,
79
+ v
80
+ ]);
81
+ };
82
+ }
83
+ function step(op) {
84
+ if (f) throw new TypeError("Generator is already executing.");
85
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
86
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
87
+ if (y = 0, t) op = [
88
+ op[0] & 2,
89
+ t.value
90
+ ];
91
+ switch(op[0]){
92
+ case 0:
93
+ case 1:
94
+ t = op;
95
+ break;
96
+ case 4:
97
+ _.label++;
98
+ return {
99
+ value: op[1],
100
+ done: false
101
+ };
102
+ case 5:
103
+ _.label++;
104
+ y = op[1];
105
+ op = [
106
+ 0
107
+ ];
108
+ continue;
109
+ case 7:
110
+ op = _.ops.pop();
111
+ _.trys.pop();
112
+ continue;
113
+ default:
114
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
115
+ _ = 0;
116
+ continue;
117
+ }
118
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
119
+ _.label = op[1];
120
+ break;
121
+ }
122
+ if (op[0] === 6 && _.label < t[1]) {
123
+ _.label = t[1];
124
+ t = op;
125
+ break;
126
+ }
127
+ if (t && _.label < t[2]) {
128
+ _.label = t[2];
129
+ _.ops.push(op);
130
+ break;
131
+ }
132
+ if (t[2]) _.ops.pop();
133
+ _.trys.pop();
134
+ continue;
135
+ }
136
+ op = body.call(thisArg, _);
137
+ } catch (e) {
138
+ op = [
139
+ 6,
140
+ e
141
+ ];
142
+ y = 0;
143
+ } finally{
144
+ f = t = 0;
145
+ }
146
+ if (op[0] & 5) throw op[1];
147
+ return {
148
+ value: op[0] ? op[1] : void 0,
149
+ done: true
150
+ };
151
+ }
152
+ }
153
+ import { BRAIN_EVENTS } from '@positronic/core';
154
+ /**
155
+ * Adapter that handles page cleanup when brains terminate.
156
+ * Non-persistent pages are deleted from R2 when a brain completes, errors, or is cancelled.
157
+ */ export var PageAdapter = /*#__PURE__*/ function() {
158
+ "use strict";
159
+ function PageAdapter(monitorStub, resourcesBucket) {
160
+ _class_call_check(this, PageAdapter);
161
+ _define_property(this, "monitorStub", void 0);
162
+ _define_property(this, "resourcesBucket", void 0);
163
+ this.monitorStub = monitorStub;
164
+ this.resourcesBucket = resourcesBucket;
165
+ }
166
+ _create_class(PageAdapter, [
167
+ {
168
+ key: "dispatch",
169
+ value: function dispatch(event) {
170
+ return _async_to_generator(function() {
171
+ var pageSlugs, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, slug, key, err, error;
172
+ return _ts_generator(this, function(_state) {
173
+ switch(_state.label){
174
+ case 0:
175
+ // Only handle terminal events
176
+ if (event.type !== BRAIN_EVENTS.COMPLETE && event.type !== BRAIN_EVENTS.ERROR && event.type !== BRAIN_EVENTS.CANCELLED) {
177
+ return [
178
+ 2
179
+ ];
180
+ }
181
+ _state.label = 1;
182
+ case 1:
183
+ _state.trys.push([
184
+ 1,
185
+ 12,
186
+ ,
187
+ 13
188
+ ]);
189
+ return [
190
+ 4,
191
+ this.monitorStub.getNonPersistentPagesForRun(event.brainRunId)
192
+ ];
193
+ case 2:
194
+ pageSlugs = _state.sent();
195
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
196
+ _state.label = 3;
197
+ case 3:
198
+ _state.trys.push([
199
+ 3,
200
+ 8,
201
+ 9,
202
+ 10
203
+ ]);
204
+ _iterator = pageSlugs[Symbol.iterator]();
205
+ _state.label = 4;
206
+ case 4:
207
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
208
+ 3,
209
+ 7
210
+ ];
211
+ slug = _step.value;
212
+ key = "pages/".concat(slug, ".html");
213
+ return [
214
+ 4,
215
+ this.resourcesBucket.delete(key)
216
+ ];
217
+ case 5:
218
+ _state.sent();
219
+ _state.label = 6;
220
+ case 6:
221
+ _iteratorNormalCompletion = true;
222
+ return [
223
+ 3,
224
+ 4
225
+ ];
226
+ case 7:
227
+ return [
228
+ 3,
229
+ 10
230
+ ];
231
+ case 8:
232
+ err = _state.sent();
233
+ _didIteratorError = true;
234
+ _iteratorError = err;
235
+ return [
236
+ 3,
237
+ 10
238
+ ];
239
+ case 9:
240
+ try {
241
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
242
+ _iterator.return();
243
+ }
244
+ } finally{
245
+ if (_didIteratorError) {
246
+ throw _iteratorError;
247
+ }
248
+ }
249
+ return [
250
+ 7
251
+ ];
252
+ case 10:
253
+ // Clear the page registrations from MonitorDO
254
+ return [
255
+ 4,
256
+ this.monitorStub.clearPageRegistrations(event.brainRunId)
257
+ ];
258
+ case 11:
259
+ _state.sent();
260
+ return [
261
+ 3,
262
+ 13
263
+ ];
264
+ case 12:
265
+ error = _state.sent();
266
+ console.error("[PageAdapter] Error cleaning up pages for brain run ".concat(event.brainRunId, ":"), error);
267
+ return [
268
+ 3,
269
+ 13
270
+ ];
271
+ case 13:
272
+ return [
273
+ 2
274
+ ];
275
+ }
276
+ });
277
+ }).call(this);
278
+ }
279
+ }
280
+ ]);
281
+ return PageAdapter;
282
+ }();
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;AAmwB/C,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;AAojC/C,eAAe,GAAG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAwC,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,wBAAgB,WAAW,CAAC,iBAAiB,EAAE,kBAAkB,QAEhE;AAED,wBAAgB,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAEvD;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,QAEjD;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAE/D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE/D;AAED,MAAM,WAAW,GAAG;IAClB,eAAe,EAAE,sBAAsB,CAAC;IACxC,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;CAC5B;AAwDD,qBAAa,aAAc,SAAQ,aAAa,CAAC,GAAG,CAAC;IACnD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,eAAe,CAAgC;gBAE3C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;YAOjC,mBAAmB;IA0E3B,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAStD,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAuF7B,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAuHhC,KAAK,CAAC,OAAO,EAAE,OAAO;CA4E7B"}
1
+ {"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAwC,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,wBAAgB,WAAW,CAAC,iBAAiB,EAAE,kBAAkB,QAEhE;AAED,wBAAgB,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAEvD;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,QAEjD;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAE/D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE/D;AAED,MAAM,WAAW,GAAG;IAClB,eAAe,EAAE,sBAAsB,CAAC;IACxC,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;CAC5B;AAwDD,qBAAa,aAAc,SAAQ,aAAa,CAAC,GAAG,CAAC;IACnD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,eAAe,CAAgC;gBAE3C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;YAOjC,mBAAmB;IA0E3B,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAStD,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyF7B,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyHhC,KAAK,CAAC,OAAO,EAAE,OAAO;CA4E7B"}
@@ -27,5 +27,24 @@ export declare class MonitorDO extends DurableObject<Env> {
27
27
  * Called when brain completes, errors, or is cancelled
28
28
  */
29
29
  clearWebhookRegistrations(brainRunId: string): void;
30
+ /**
31
+ * Register a page for tracking
32
+ * Called when a page is created via the API
33
+ */
34
+ registerPage(slug: string, brainRunId: string, persist: boolean): void;
35
+ /**
36
+ * Unregister a page (when deleted via API)
37
+ */
38
+ unregisterPage(slug: string): void;
39
+ /**
40
+ * Get all non-persistent page slugs for a brain run
41
+ * Used by PageAdapter to clean up pages when brain terminates
42
+ */
43
+ getNonPersistentPagesForRun(brainRunId: string): string[];
44
+ /**
45
+ * Clear all page registrations for a brain run
46
+ * Called after pages are cleaned up
47
+ */
48
+ clearPageRegistrations(brainRunId: string): void;
30
49
  }
31
50
  //# sourceMappingURL=monitor-do.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"monitor-do.d.ts","sourceRoot":"","sources":["../../src/monitor-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,GAAG;CAEnB;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,GAAG,CAAC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAyC/C,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;YA4DzB,sBAAsB;IA0B9B,KAAK,CAAC,OAAO,EAAE,OAAO;IA0D5B,YAAY,CAAC,UAAU,EAAE,MAAM;IAc/B,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW;IA6B9C,UAAU,CAAC,UAAU,EAAE,MAAM;IAyB7B;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAapE;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiBjE;;;OAGG;IACH,yBAAyB,CAAC,UAAU,EAAE,MAAM;CAS7C"}
1
+ {"version":3,"file":"monitor-do.d.ts","sourceRoot":"","sources":["../../src/monitor-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,GAAG;CAEnB;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,GAAG,CAAC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAuD/C,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;YA8DzB,sBAAsB;IA0B9B,KAAK,CAAC,OAAO,EAAE,OAAO;IA0D5B,YAAY,CAAC,UAAU,EAAE,MAAM;IAc/B,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW;IA6B9C,UAAU,CAAC,UAAU,EAAE,MAAM;IAyB7B;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAapE;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiBjE;;;OAGG;IACH,yBAAyB,CAAC,UAAU,EAAE,MAAM;IAU5C;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAgB/D;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM;IAU3B;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAezD;;;OAGG;IACH,sBAAsB,CAAC,UAAU,EAAE,MAAM;CAS1C"}
@@ -0,0 +1,16 @@
1
+ import type { Adapter, BrainEvent } from '@positronic/core';
2
+ import type { R2Bucket } from '@cloudflare/workers-types';
3
+ /**
4
+ * Adapter that handles page cleanup when brains terminate.
5
+ * Non-persistent pages are deleted from R2 when a brain completes, errors, or is cancelled.
6
+ */
7
+ export declare class PageAdapter implements Adapter {
8
+ private monitorStub;
9
+ private resourcesBucket;
10
+ constructor(monitorStub: {
11
+ getNonPersistentPagesForRun: (brainRunId: string) => Promise<string[]>;
12
+ clearPageRegistrations: (brainRunId: string) => Promise<void>;
13
+ }, resourcesBucket: R2Bucket);
14
+ dispatch(event: BrainEvent): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=page-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-adapter.d.ts","sourceRoot":"","sources":["../../src/page-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D;;;GAGG;AACH,qBAAa,WAAY,YAAW,OAAO;IAEvC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,eAAe;gBAJf,WAAW,EAAE;QACnB,2BAA2B,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC/D,EACO,eAAe,EAAE,QAAQ;IAG7B,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAgCjD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@positronic/cloudflare",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,9 +31,9 @@
31
31
  "clean": "rm -rf tsconfig.tsbuildinfo dist"
32
32
  },
33
33
  "dependencies": {
34
- "@positronic/core": "^0.0.20",
35
- "@positronic/spec": "^0.0.20",
36
- "@positronic/template-new-project": "^0.0.20",
34
+ "@positronic/core": "^0.0.22",
35
+ "@positronic/spec": "^0.0.22",
36
+ "@positronic/template-new-project": "^0.0.22",
37
37
  "aws4fetch": "^1.0.18",
38
38
  "caz": "^2.0.0",
39
39
  "cron-schedule": "^5.0.4",