Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions templates/keynote-2/module_bindings/create_account_reducer.ts

This file was deleted.

9 changes: 5 additions & 4 deletions templates/keynote-2/module_bindings/index.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion templates/keynote-2/module_bindings/transfer_reducer.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions templates/keynote-2/module_bindings/types/reducers.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 2 additions & 15 deletions templates/keynote-2/rust_module/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use spacetimedb::{reducer, ReducerContext, Table};
#[derive(Debug, Clone)]
pub struct Accounts {
#[primary_key]
#[index(hash)]
pub id: u32,
pub balance: i64,
}
Expand All @@ -31,21 +32,7 @@ pub fn seed(ctx: &ReducerContext, n: u32, initial_balance: i64) -> Result<(), St
}

#[reducer]
pub fn create_account(ctx: &ReducerContext, id: u32, balance: i64) -> Result<(), String> {
let accounts = ctx.db.accounts();
let by_id = accounts.id();

if let Some(mut row) = by_id.find(&id) {
row.balance = balance;
by_id.update(row);
} else {
accounts.insert(Accounts { id, balance });
}
Ok(())
}

#[reducer]
pub fn transfer(ctx: &ReducerContext, from: u32, to: u32, amount: i64, _client_txn_id: u64) -> Result<(), String> {
pub fn transfer(ctx: &ReducerContext, from: u32, to: u32, amount: i64) -> Result<(), String> {
if from == to {
return Err("same_account".into());
}
Expand Down
31 changes: 20 additions & 11 deletions templates/keynote-2/spacetimedb/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { schema, table, t, SenderError } from 'spacetimedb/server';

const spacetimedb = schema({
account: table(
{ name: 'account' },
accounts: table(
{ name: 'accounts', public: true },
{
id: t.u32().primaryKey().index('hash'),
balance: t.i64(),
Expand All @@ -12,9 +12,9 @@ const spacetimedb = schema({
export default spacetimedb;

export const seed = spacetimedb.reducer(
{ n: t.u32(), balance: t.i64() },
(ctx, { n, balance }) => {
const accounts = ctx.db.account;
{ n: t.u32(), initialBalance: t.i64() },
(ctx, { n, initialBalance: balance }) => {
const accounts = ctx.db.accounts;

for (const row of accounts) {
accounts.delete(row);
Expand All @@ -27,15 +27,24 @@ export const seed = spacetimedb.reducer(
);

export const transfer = spacetimedb.reducer(
{ from: t.u32(), to: t.u32(), amount: t.u32() },
(ctx, { from, to, amount: amt }) => {
const accounts = ctx.db.account;
{ from: t.u32(), to: t.u32(), amount: t.i64() },
(ctx, { from, to, amount }) => {
if (from === to) {
throw new SenderError('same_account');
}
if (amount <= 0) {
throw new SenderError('non_positive_amount');
}

const accounts = ctx.db.accounts;
const byId = accounts.id;

const fromRow = byId.find(from)!;
const toRow = byId.find(to)!;
const fromRow = byId.find(from);
const toRow = byId.find(to);
if (fromRow === null || toRow === null) {
throw new SenderError('account_missing');
}

const amount = BigInt(amt);
if (fromRow.balance < amount) {
throw new SenderError('insufficient_funds');
}
Expand Down
2 changes: 1 addition & 1 deletion templates/keynote-2/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ const testDirPath = fileURLToPath(testDirUrl);

if (connectors && !connectors.includes(tc.system)) continue;

const makeConnector = (CONNECTORS as any)[tc.system];
const makeConnector = CONNECTORS[tc.system];
if (!makeConnector) throw new Error(`Unknown connector ${tc.system}`);

const connector = makeConnector();
Expand Down
110 changes: 6 additions & 104 deletions templates/keynote-2/src/connectors/spacetimedb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ export function spacetimedb(
});
}

// --- reducer completion tracking ------------------------
const transferWaiters = new Map<
bigint,
{ resolve: () => void; reject: (e: unknown) => void }
>();

let nextTransferId = 1n;
let transferHooked = false;

async function connectWithBindings() {
if (!url) throw new Error('STDB_URL not set');
if (!moduleName) throw new Error('STDB_MODULE not set');
Expand All @@ -49,53 +40,6 @@ export function spacetimedb(
console.log('[stdb] connected');
const conn = ctx;

const reducers = conn.reducers;

if (
process.env.USE_SPACETIME_METRICS_ENDPOINT === '0' &&
!transferHooked
) {
transferHooked = true;
console.log('[stdb] hooking onTransfer');
(reducers as any).onTransfer(
(
eventCtx: any,
args: {
from: number;
to: number;
amount: bigint;
clientTxnId: bigint;
},
) => {
const clientTxnId = args.clientTxnId;
// console.log('[stdb] onTransfer fired', { ...args, status: eventCtx?.event?.status });

const waiter = transferWaiters.get(clientTxnId);
if (!waiter) {
console.warn(
'[stdb] no waiter for clientTxnId',
clientTxnId.toString(),
);
return;
}

transferWaiters.delete(clientTxnId);

const status = eventCtx?.event?.status;

if (status?.tag === 'Committed') {
waiter.resolve();
} else if (status?.tag === 'Failed') {
waiter.reject(new Error(status?.value ?? 'transfer failed'));
} else if (status?.tag === 'OutOfEnergy') {
waiter.reject(new Error('transfer out of energy'));
} else {
waiter.reject(new Error('unknown transfer status'));
}
},
);
}

resolveReady();

if (subscriptions.length > 0) {
Expand Down Expand Up @@ -147,19 +91,6 @@ export function spacetimedb(
},

async close() {
const err = new Error('SpacetimeDB connection closed');

// Fail any in-flight transfers
for (const waiter of transferWaiters.values()) {
try {
waiter.reject(err);
} catch {
/* ignore */
}
}
transferWaiters.clear();
transferHooked = false;

try {
conn.disconnect();
} catch (e) {
Expand All @@ -184,47 +115,18 @@ export function spacetimedb(

switch (fn) {
case 'seed': {
conn.reducers.seed({
return conn.reducers.seed({
n: args.accounts,
initialBalance: args.initialBalance,
});
return;
}

case 'createAccount': {
conn.reducers.createAccount({ id: args.id, balance: args.balance });
return;
}

case 'transfer': {
const clientTxnId = nextTransferId++;

if (process.env.USE_SPACETIME_METRICS_ENDPOINT === '0') {
return new Promise<void>((resolve, reject) => {
const waiter = { resolve, reject };
transferWaiters.set(clientTxnId, waiter);

try {
conn.reducers.transfer({
from: args.from,
to: args.to,
amount: args.amount,
clientTxnId,
});
} catch (err) {
console.log(`ERROR ${err}`);
transferWaiters.delete(clientTxnId);
reject(err);
}
});
} else {
return conn.reducers.transfer({
from: args.from,
to: args.to,
amount: args.amount,
clientTxnId,
});
}
return conn.reducers.transfer({
from: args.from,
to: args.to,
amount: args.amount,
});
}

default:
Expand Down
Loading