@livefolio/sdk 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +191 -0
  2. package/dist/auth/client.d.ts +4 -0
  3. package/dist/auth/client.d.ts.map +1 -0
  4. package/dist/auth/client.js +37 -0
  5. package/dist/auth/client.js.map +1 -0
  6. package/dist/auth/index.d.ts +3 -0
  7. package/dist/auth/index.d.ts.map +1 -0
  8. package/dist/auth/index.js +6 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/auth/types.d.ts +9 -0
  11. package/dist/auth/types.d.ts.map +1 -0
  12. package/dist/auth/types.js +3 -0
  13. package/dist/auth/types.js.map +1 -0
  14. package/dist/index.d.ts +23 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +55 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/market/client.d.ts +4 -0
  19. package/dist/market/client.d.ts.map +1 -0
  20. package/dist/market/client.js +65 -0
  21. package/dist/market/client.js.map +1 -0
  22. package/dist/market/index.d.ts +3 -0
  23. package/dist/market/index.d.ts.map +1 -0
  24. package/dist/market/index.js +6 -0
  25. package/dist/market/index.js.map +1 -0
  26. package/dist/market/types.d.ts +20 -0
  27. package/dist/market/types.d.ts.map +1 -0
  28. package/dist/market/types.js +3 -0
  29. package/dist/market/types.js.map +1 -0
  30. package/dist/portfolio/client.d.ts +4 -0
  31. package/dist/portfolio/client.d.ts.map +1 -0
  32. package/dist/portfolio/client.js +7 -0
  33. package/dist/portfolio/client.js.map +1 -0
  34. package/dist/portfolio/index.d.ts +3 -0
  35. package/dist/portfolio/index.d.ts.map +1 -0
  36. package/dist/portfolio/index.js +6 -0
  37. package/dist/portfolio/index.js.map +1 -0
  38. package/dist/portfolio/types.d.ts +3 -0
  39. package/dist/portfolio/types.d.ts.map +1 -0
  40. package/dist/portfolio/types.js +3 -0
  41. package/dist/portfolio/types.js.map +1 -0
  42. package/dist/strategy/client.d.ts +4 -0
  43. package/dist/strategy/client.d.ts.map +1 -0
  44. package/dist/strategy/client.js +350 -0
  45. package/dist/strategy/client.js.map +1 -0
  46. package/dist/strategy/evaluate.d.ts +10 -0
  47. package/dist/strategy/evaluate.d.ts.map +1 -0
  48. package/dist/strategy/evaluate.js +498 -0
  49. package/dist/strategy/evaluate.js.map +1 -0
  50. package/dist/strategy/index.d.ts +6 -0
  51. package/dist/strategy/index.d.ts.map +1 -0
  52. package/dist/strategy/index.js +20 -0
  53. package/dist/strategy/index.js.map +1 -0
  54. package/dist/strategy/symbols.d.ts +4 -0
  55. package/dist/strategy/symbols.d.ts.map +1 -0
  56. package/dist/strategy/symbols.js +41 -0
  57. package/dist/strategy/symbols.js.map +1 -0
  58. package/dist/strategy/time.d.ts +9 -0
  59. package/dist/strategy/time.d.ts.map +1 -0
  60. package/dist/strategy/time.js +28 -0
  61. package/dist/strategy/time.js.map +1 -0
  62. package/dist/strategy/types.d.ts +107 -0
  63. package/dist/strategy/types.d.ts.map +1 -0
  64. package/dist/strategy/types.js +3 -0
  65. package/dist/strategy/types.js.map +1 -0
  66. package/dist/types.d.ts +4 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +3 -0
  69. package/dist/types.js.map +1 -0
  70. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # @livefolio/sdk
2
+
3
+ TypeScript SDK for market data, strategy evaluation, and portfolio management.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @livefolio/sdk
9
+ ```
10
+
11
+ ## Getting Started
12
+
13
+ All modules are created from a single Supabase client:
14
+
15
+ ```ts
16
+ import { createLivefolioClient } from '@livefolio/sdk';
17
+ import { createClient } from '@supabase/supabase-js';
18
+
19
+ const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
20
+ const livefolio = createLivefolioClient(supabase);
21
+ ```
22
+
23
+ Individual modules can also be imported directly:
24
+
25
+ ```ts
26
+ import { createMarket } from '@livefolio/sdk/market';
27
+ import { createAuth } from '@livefolio/sdk/auth';
28
+ import { createStrategy } from '@livefolio/sdk/strategy';
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Auth
34
+
35
+ Wraps Supabase Auth with a simplified interface.
36
+
37
+ | Method | Returns | Description |
38
+ |--------|---------|-------------|
39
+ | `getUser()` | `User \| null` | Get the current authenticated user, or `null` if not signed in |
40
+ | `getSession()` | `Session \| null` | Get the current session |
41
+ | `requireUser()` | `User` | Get the current user or throw if not authenticated |
42
+ | `onAuthStateChange(callback)` | `Subscription` | Subscribe to auth state changes (sign in, sign out, token refresh) |
43
+ | `signOut()` | `void` | Sign out the current user |
44
+
45
+ ```ts
46
+ const user = await livefolio.auth.getUser();
47
+
48
+ const subscription = livefolio.auth.onAuthStateChange((event, session) => {
49
+ console.log(event, session);
50
+ });
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Market
56
+
57
+ Provides historical price series, real-time quotes, and the trading calendar. Series and quotes are served through Supabase Edge Functions with transparent cache-through behavior — the SDK requests data and caching is handled server-side.
58
+
59
+ ### Series
60
+
61
+ Retrieve historical daily observations for one or more symbols. Each observation has an ISO 8601 `timestamp` (market close) and a `value` (closing price).
62
+
63
+ ```ts
64
+ const spy = await livefolio.market.getSeries('SPY');
65
+ // spy: Observation[] — [{ timestamp: '2025-01-10T21:00:00Z', value: 590.25 }, ...]
66
+
67
+ const batch = await livefolio.market.getBatchSeries(['SPY', 'QQQ', 'TLT']);
68
+ // batch: Record<string, Observation[]> — { SPY: [...], QQQ: [...], TLT: [...] }
69
+ ```
70
+
71
+ ### Quotes
72
+
73
+ Retrieve the latest real-time quote for one or more symbols.
74
+
75
+ ```ts
76
+ const quote = await livefolio.market.getQuote('SPY');
77
+ // quote: Observation — { timestamp: '2025-03-02T21:00:00Z', value: 592.10 }
78
+
79
+ const quotes = await livefolio.market.getBatchQuotes(['SPY', 'QQQ']);
80
+ // quotes: Record<string, Observation>
81
+ ```
82
+
83
+ ### Trading Calendar
84
+
85
+ Query the trading calendar for market open/close times. Dates are `YYYY-MM-DD` strings.
86
+
87
+ ```ts
88
+ const days = await livefolio.market.getTradingDays('2025-01-01', '2025-12-31');
89
+ // days: TradingDay[] — [{ date, open, close, extended_open, extended_close }, ...]
90
+
91
+ const today = await livefolio.market.getTradingDay('2025-03-02');
92
+ // today: TradingDay | null
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Strategy
98
+
99
+ Handles strategy retrieval, evaluation, and result caching. The module exposes two evaluation paths:
100
+
101
+ - **`evaluate()`** (async) — the primary API. Checks the DB cache for a prior result, returns it on hit, or runs a fresh evaluation and stores the result on miss. Consumers never need to manage caching manually.
102
+ - **Pure functions** (sync) — `evaluateIndicator`, `evaluateSignal`, `evaluateAllocation` for direct computation without DB interaction. Useful for testing, debugging, or custom pipelines.
103
+
104
+ ### Retrieving Strategies
105
+
106
+ Fetch a fully-resolved strategy by its link ID. The `get()` method calls the `strategy` edge function, which looks up the strategy in the database and auto-imports from testfol.io if not found. The returned `Strategy` object contains all named signals, indicators, condition trees, and allocations ready for evaluation.
107
+
108
+ ```ts
109
+ const strategy = await livefolio.strategy.get('abc-123');
110
+ // strategy: Strategy | null
111
+
112
+ const strategies = await livefolio.strategy.getMany(['abc-123', 'def-456']);
113
+ // strategies: Record<string, Strategy>
114
+ ```
115
+
116
+ ### Evaluating a Strategy
117
+
118
+ The `evaluate` method is the standard way to run a strategy. Pass a strategy and a date — everything else is handled internally:
119
+
120
+ 1. Fetches historical series for all symbols used by the strategy
121
+ 2. Computes the evaluation date
122
+ 3. Checks the DB cache for a prior result on that trading day
123
+ 4. On cache miss: fetches prior signal states (for hysteresis) and indicator metadata (for incremental EMA/RSI), runs the evaluation, and stores the result
124
+ 5. On cache hit: returns the cached allocation and signal states
125
+
126
+ ```ts
127
+ const strategy = await livefolio.strategy.get('abc-123');
128
+ if (strategy) {
129
+ const result = await livefolio.strategy.evaluate(strategy, new Date());
130
+
131
+ result.allocation; // the winning allocation (name, holdings)
132
+ result.asOf; // Date the evaluation corresponds to (trading day market close)
133
+ result.signals; // Record<string, boolean> — all signal states
134
+ result.indicators; // Record<string, IndicatorEvaluation> — all indicator values
135
+ }
136
+ ```
137
+
138
+ ### Utilities
139
+
140
+ | Method | Returns | Description |
141
+ |--------|---------|-------------|
142
+ | `extractSymbols(strategy)` | `string[]` | Collect all ticker symbols needed to evaluate a strategy (from signals + holdings) |
143
+ | `getEvaluationDate(trading, options)` | `Date` | Compute the evaluation date — requires `EvaluationOptions` with series data |
144
+
145
+ ### Pure Evaluation Functions
146
+
147
+ For advanced use cases (testing, backtesting, custom pipelines), the pure evaluation functions operate synchronously without any DB interaction. They accept `EvaluationOptions` with `batchSeries` and optionally `previousSignalStates` and `previousIndicatorMetadata`.
148
+
149
+ ```ts
150
+ import { evaluate, evaluateIndicator, evaluateSignal } from '@livefolio/sdk/strategy';
151
+
152
+ // Evaluate a single indicator
153
+ const smaResult = livefolio.strategy.evaluateIndicator(indicator, options);
154
+
155
+ // Evaluate a signal (comparison of two indicators)
156
+ const isAbove = livefolio.strategy.evaluateSignal(signal, options);
157
+
158
+ // Evaluate a full allocation condition tree
159
+ const matches = livefolio.strategy.evaluateAllocation(allocation, options);
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Portfolio
165
+
166
+ Brokerage account aggregation and trade order management. This module is planned but not yet implemented.
167
+
168
+ ---
169
+
170
+ ## Development
171
+
172
+ ```bash
173
+ npm install
174
+ npm run build # compile TypeScript → dist/
175
+ npm test # run tests
176
+ ```
177
+
178
+ ## CI/CD
179
+
180
+ - PRs to `main` run build + tests and enforce a version bump
181
+ - Merges to `main` auto-publish to npm and create a GitHub release
182
+
183
+ Before merging, bump the version:
184
+
185
+ ```bash
186
+ npm version patch
187
+ ```
188
+
189
+ ## License
190
+
191
+ MIT
@@ -0,0 +1,4 @@
1
+ import type { TypedSupabaseClient } from '../types';
2
+ import type { AuthModule } from './types';
3
+ export declare function createAuth(client: TypedSupabaseClient): AuthModule;
4
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,UAAU,CA+BlE"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuth = createAuth;
4
+ function createAuth(client) {
5
+ return {
6
+ async getUser() {
7
+ const { data, error } = await client.auth.getUser();
8
+ if (error)
9
+ throw error;
10
+ return data.user;
11
+ },
12
+ async getSession() {
13
+ const { data, error } = await client.auth.getSession();
14
+ if (error)
15
+ throw error;
16
+ return data.session;
17
+ },
18
+ async requireUser() {
19
+ const { data, error } = await client.auth.getUser();
20
+ if (error)
21
+ throw error;
22
+ if (!data.user)
23
+ throw new Error('Not authenticated');
24
+ return data.user;
25
+ },
26
+ onAuthStateChange(callback) {
27
+ const { data } = client.auth.onAuthStateChange(callback);
28
+ return data.subscription;
29
+ },
30
+ async signOut() {
31
+ const { error } = await client.auth.signOut();
32
+ if (error)
33
+ throw error;
34
+ },
35
+ };
36
+ }
37
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":";;AAGA,gCA+BC;AA/BD,SAAgB,UAAU,CAAC,MAA2B;IACpD,OAAO;QACL,KAAK,CAAC,OAAO;YACX,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,KAAK,CAAC,UAAU;YACd,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACvD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAED,KAAK,CAAC,WAAW;YACf,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACrD,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,iBAAiB,CAAC,QAAQ;YACxB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9C,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { AuthModule } from './types';
2
+ export { createAuth } from './client';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuth = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "createAuth", { enumerable: true, get: function () { return client_1.createAuth; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;AACA,mCAAsC;AAA7B,oGAAA,UAAU,OAAA"}
@@ -0,0 +1,9 @@
1
+ import type { User, Session, AuthChangeEvent, Subscription } from '@supabase/supabase-js';
2
+ export interface AuthModule {
3
+ getUser(): Promise<User | null>;
4
+ getSession(): Promise<Session | null>;
5
+ requireUser(): Promise<User>;
6
+ onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => void): Subscription;
7
+ signOut(): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1F,MAAM,WAAW,UAAU;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAChC,UAAU,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,iBAAiB,CACf,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,GAClE,YAAY,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ export * as auth from './auth';
2
+ export * as market from './market';
3
+ export * as strategy from './strategy';
4
+ export * as portfolio from './portfolio';
5
+ export type { TypedSupabaseClient } from './types';
6
+ export type { AuthModule } from './auth';
7
+ export type { MarketModule } from './market';
8
+ export type { StrategyModule } from './strategy';
9
+ export type { PortfolioModule } from './portfolio';
10
+ import type { TypedSupabaseClient } from './types';
11
+ import type { AuthModule } from './auth';
12
+ import type { MarketModule } from './market';
13
+ import type { StrategyModule } from './strategy';
14
+ import type { PortfolioModule } from './portfolio';
15
+ export interface LivefolioClient {
16
+ readonly supabase: TypedSupabaseClient;
17
+ readonly auth: AuthModule;
18
+ readonly market: MarketModule;
19
+ readonly strategy: StrategyModule;
20
+ readonly portfolio: PortfolioModule;
21
+ }
22
+ export declare function createLivefolioClient(supabase: TypedSupabaseClient): LivefolioClient;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAEzC,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;CACrC;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,eAAe,CAQpF"}
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.portfolio = exports.strategy = exports.market = exports.auth = void 0;
37
+ exports.createLivefolioClient = createLivefolioClient;
38
+ exports.auth = __importStar(require("./auth"));
39
+ exports.market = __importStar(require("./market"));
40
+ exports.strategy = __importStar(require("./strategy"));
41
+ exports.portfolio = __importStar(require("./portfolio"));
42
+ const auth_1 = require("./auth");
43
+ const market_1 = require("./market");
44
+ const strategy_1 = require("./strategy");
45
+ const portfolio_1 = require("./portfolio");
46
+ function createLivefolioClient(supabase) {
47
+ return {
48
+ supabase,
49
+ auth: (0, auth_1.createAuth)(supabase),
50
+ market: (0, market_1.createMarket)(supabase),
51
+ strategy: (0, strategy_1.createStrategy)(supabase),
52
+ portfolio: (0, portfolio_1.createPortfolio)(supabase),
53
+ };
54
+ }
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,sDAQC;AArCD,+CAA+B;AAC/B,mDAAmC;AACnC,uDAAuC;AACvC,yDAAyC;AAazC,iCAAoC;AACpC,qCAAwC;AACxC,yCAA4C;AAC5C,2CAA8C;AAU9C,SAAgB,qBAAqB,CAAC,QAA6B;IACjE,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,IAAA,iBAAU,EAAC,QAAQ,CAAC;QAC1B,MAAM,EAAE,IAAA,qBAAY,EAAC,QAAQ,CAAC;QAC9B,QAAQ,EAAE,IAAA,yBAAc,EAAC,QAAQ,CAAC;QAClC,SAAS,EAAE,IAAA,2BAAe,EAAC,QAAQ,CAAC;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { TypedSupabaseClient } from '../types';
2
+ import type { MarketModule } from './types';
3
+ export declare function createMarket(client: TypedSupabaseClient): MarketModule;
4
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/market/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAA2B,YAAY,EAAE,MAAM,SAAS,CAAC;AAErE,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY,CAgEtE"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMarket = createMarket;
4
+ function createMarket(client) {
5
+ return {
6
+ async getBatchSeries(symbols) {
7
+ const { data, error } = await client.functions.invoke('series', { body: { symbols } });
8
+ if (error)
9
+ throw error;
10
+ return data;
11
+ },
12
+ async getSeries(symbol) {
13
+ const result = await this.getBatchSeries([symbol]);
14
+ return result[symbol];
15
+ },
16
+ async getBatchQuotes(symbols) {
17
+ const { data, error } = await client.functions.invoke('quote', { body: { symbols } });
18
+ if (error)
19
+ throw error;
20
+ return data;
21
+ },
22
+ async getQuote(symbol) {
23
+ const result = await this.getBatchQuotes([symbol]);
24
+ const quote = result[symbol];
25
+ if (quote == null)
26
+ throw new Error(`No quote available for ${symbol}`);
27
+ return quote;
28
+ },
29
+ async getTradingDays(startDate, endDate) {
30
+ const { data, error } = await client
31
+ .from('trading_days')
32
+ .select('date, overnight, pre, regular, post, close')
33
+ .gte('date', startDate)
34
+ .lte('date', endDate)
35
+ .order('date', { ascending: true });
36
+ if (error)
37
+ throw new Error(`Failed to fetch trading days: ${error.message}`);
38
+ return (data ?? []).map((row) => ({
39
+ date: row.date,
40
+ open: row.regular,
41
+ close: row.post,
42
+ extended_open: row.overnight,
43
+ extended_close: row.close,
44
+ }));
45
+ },
46
+ async getTradingDay(date) {
47
+ const { data: row, error } = await client
48
+ .from('trading_days')
49
+ .select('date, overnight, pre, regular, post, close')
50
+ .eq('date', date)
51
+ .limit(1)
52
+ .maybeSingle();
53
+ if (error || !row)
54
+ return null;
55
+ return {
56
+ date: row.date,
57
+ open: row.regular,
58
+ close: row.post,
59
+ extended_open: row.overnight,
60
+ extended_close: row.close,
61
+ };
62
+ },
63
+ };
64
+ }
65
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/market/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type { Observation, TradingDay, MarketModule } from './types';
2
+ export { createMarket } from './client';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/market/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMarket = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "createMarket", { enumerable: true, get: function () { return client_1.createMarket; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/market/index.ts"],"names":[],"mappings":";;;AACA,mCAAwC;AAA/B,sGAAA,YAAY,OAAA"}
@@ -0,0 +1,20 @@
1
+ export interface Observation {
2
+ timestamp: string;
3
+ value: number;
4
+ }
5
+ export interface TradingDay {
6
+ date: string;
7
+ open: string;
8
+ close: string;
9
+ extended_open: string;
10
+ extended_close: string;
11
+ }
12
+ export interface MarketModule {
13
+ getSeries(symbol: string): Promise<Observation[]>;
14
+ getBatchSeries(symbols: string[]): Promise<Record<string, Observation[]>>;
15
+ getQuote(symbol: string): Promise<Observation>;
16
+ getBatchQuotes(symbols: string[]): Promise<Record<string, Observation>>;
17
+ getTradingDays(startDate: string, endDate: string): Promise<TradingDay[]>;
18
+ getTradingDay(date: string): Promise<TradingDay | null>;
19
+ }
20
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/market/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAE3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IAG1E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAGxE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CACzD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/market/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { TypedSupabaseClient } from '../types';
2
+ import type { PortfolioModule } from './types';
3
+ export declare function createPortfolio(_client: TypedSupabaseClient): PortfolioModule;
4
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/portfolio/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,eAAe,CAE7E"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPortfolio = createPortfolio;
4
+ function createPortfolio(_client) {
5
+ return {};
6
+ }
7
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/portfolio/client.ts"],"names":[],"mappings":";;AAGA,0CAEC;AAFD,SAAgB,eAAe,CAAC,OAA4B;IAC1D,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { PortfolioModule } from './types';
2
+ export { createPortfolio } from './client';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/portfolio/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPortfolio = void 0;
4
+ var client_1 = require("./client");
5
+ Object.defineProperty(exports, "createPortfolio", { enumerable: true, get: function () { return client_1.createPortfolio; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/portfolio/index.ts"],"names":[],"mappings":";;;AACA,mCAA2C;AAAlC,yGAAA,eAAe,OAAA"}
@@ -0,0 +1,3 @@
1
+ export interface PortfolioModule {
2
+ }
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/portfolio/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;CAE/B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/portfolio/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { TypedSupabaseClient } from '../types';
2
+ import type { StrategyModule } from './types';
3
+ export declare function createStrategy(client: TypedSupabaseClient): StrategyModule;
4
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/strategy/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAMV,cAAc,EAOf,MAAM,SAAS,CAAC;AAwEjB,wBAAgB,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,cAAc,CAwX1E"}