Skip to content

Conversation

@coolreader18
Copy link
Collaborator

Description of Changes

Haven't changed schema() to accept an object yet, maybe that's for a followup?

Expected complexity level and risk

Testing

@coolreader18 coolreader18 added the api-break A PR that makes an API breaking change label Feb 6, 2026
@coolreader18 coolreader18 force-pushed the noa/ts-exports branch 3 times, most recently from 115f08a to ac98ef9 Compare February 6, 2026 19:58

let maj_sys_ver = maj_sys_ver.context(
"Your module doesn't import the `spacetimedb/server` package at all - \
this is likely a mistake, as your module will not be able to do anything",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this is likely a mistake, as your module will not be able to do anything",
this is likely a mistake, as your module will not be able to interface with the SpacetimeDB host.",

if maj_sys_ver == 2 {
anyhow::ensure!(
output_chunk.exports.contains(&"default".into()),
"It seems like you haven't exported your schema. You must `export default spacetime;`"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"It seems like you haven't exported your schema. You must `export default spacetime;`"
"It seems like you haven't exported your schema. You must `export default schema(...);`"

Copy link
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial thoughts. I'd also appreciate a longer PR description for this one :)

/// The actual callable module hook functions and their abi version.
pub(in super::super) struct HookFunctions<'scope> {
pub abi: AbiVersion,
pub recv: Local<'scope, v8::Value>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field is non-obvious, would be good to add a doc comment.

let eval_steps = |context, module| {
($scope:expr, $module_name:expr $(, ($($fun:tt)*))* $(,)?) => {{
let export_names = &[$(create_synthetic_module!(@export_name ($($fun)*)).string($scope)),*];
let eval_steps = |context: v8::Local<v8::Context>, module: v8::Local<v8::Module>| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local is already imported. For v8:: stuff, our code does not qualify stuff with v8::, so let's keep these as unqualified paths. (Applies generally in the PR.)

(@export_name ($name:ident = $value:expr)) => {
str_from_ident!($name)
};
(@register $scope:expr, $module:expr, ($name:ident = $value:expr)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, the @private_thing convention for macros produces code that's hard to read as it requires you to first understand the macros syntax and should imo only be used when it's needed for exporting macros from crates and then it should be well documented. Here, that's unnecessary, as it's all internal to the module. Instead, more macros can be made.

Comment on lines +284 to +285
default_export: Local<'_, v8::Value>,
exports_obj: Local<'_, v8::Object>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default_export: Local<'_, v8::Value>,
exports_obj: Local<'_, v8::Object>,
default_export: Local<'_, Value>,
exports_obj: Local<'_, Object>,

// Convert `hooks` to an object.
let hooks = cast!(scope, args.get(0), Object, "hooks object").map_err(|e| e.throw(scope))?;
let hooks_fn = default_export
.try_cast::<v8::Object>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.try_cast::<v8::Object>()
.try_cast::<Object>()


// Find the `__call_reducer__` function.
let hook_functions = get_hooks(scope).context("The `spacetimedb/server` module was never imported")?;
// Find the `__call_reducer__` function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment needs an update, not just call_reducer anymore.

Either::Right(mcc) => (&mcc.replica_ctx, &mcc.scheduler),
};
let instance_env = InstanceEnv::new(replica_ctx.clone(), scheduler.clone());
scope.set_slot(JsInstanceEnv::new(instance_env));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, the change in ordering also changes semantics such that e.g., __describe_module__ now is able to make syscalls. This does match WASM, so this OK.

}
};

// Setup the instance common and environment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment outdated now

// Setup the instance common and environment.
let info = &module_common.info();
let mut instance_common = InstanceCommon::new(&module_common);
let replica_ctx: &Arc<ReplicaContext> = module_common.replica_ctx();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already in scope now? This is unnecessary now?

scope: &mut PinScope<'scope, '_>,
body: impl FnOnce(&mut PinScope<'scope, '_>) -> Result<T, ErrorOrException<ExceptionThrown>>,
) -> Result<T, ErrorOrException<JsError>> {
tc_scope!(scope, scope);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're making two tc_scopes here now... that doesn't seem right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, yep, that was a mistake.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-break A PR that makes an API breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants