2. Keep the trip in native code
A Trip class that holds its fixes natively, and a summary returned as a copied object.
const seconds = (b.time - a.time) / 1000; return seconds > 0 ? distance(a, b) / seconds : 0;}
export type TripSummary = { fixes: number; meters: number; seconds: number; topSpeed: number };
/** A trip keeps its fixes in native code; JavaScript holds the Trip. */export class Trip { private fixes: Fix[] = [];
add(fix: Fix): void { this.fixes.push(fix); }
get count(): number { return this.fixes.length; }
summary(): TripSummary { let meters = 0; let topSpeed = 0; for (let i = 1; i < this.fixes.length; i++) { const a = this.fixes[i - 1]!; const b = this.fixes[i]!; meters += distance(a, b); topSpeed = Math.max(topSpeed, speed(a, b)); } const first = this.fixes[0]; const last = this.fixes[this.fixes.length - 1]; const seconds = first && last ? (last.time - first.time) / 1000 : 0; return { fixes: this.fixes.length, meters, seconds, topSpeed }; }}import { Text } from "react-native";import { distance, speed } from "./src/trip.lucent";import { Trip } from "./src/trip.lucent";
// The Eiffel Tower, then the Louvre 40 minutes later.const start = { latitude: 48.8584, longitude: 2.2945, time: 0 };const end = { latitude: 48.8606, longitude: 2.3376, time: 40 * 60 * 1000 };// A walk along the Seine, one fix every ten minutes.const walk = [ { latitude: 48.8584, longitude: 2.2945, time: 0 }, { latitude: 48.8637, longitude: 2.3023, time: 10 * 60 * 1000 }, { latitude: 48.8661, longitude: 2.3125, time: 20 * 60 * 1000 }, { latitude: 48.8638, longitude: 2.3252, time: 30 * 60 * 1000 }, { latitude: 48.8606, longitude: 2.3376, time: 40 * 60 * 1000 },];
const trip = new Trip();for (const fix of walk) trip.add(fix);
export default function App() { const summary = trip.summary(); return ( <Text> {(distance(start, end) / 1000).toFixed(2)} km at {speed(start, end).toFixed(1)} m/s {summary.fixes} fixes, {(summary.meters / 1000).toFixed(2)} km, top speed{" "} {summary.topSpeed.toFixed(1)} m/s </Text> );}Trip is a class, so JavaScript gets a handle on one native object rather than a copy. Its fixes stay in native code: JavaScript sends each fix once, with add.
What's copied, and what isn't
Section titled “What's copied, and what isn't”trip.add(fix)copies the fix. Changingfixin JavaScript afterwards doesn't change the trip.trip.summary()returns a new object on each call: a copy of aTripSummarystruct.tripitself crosses by reference. Passing it back to Lucent later gives the same object, with its fixes.trip.countis a getter: reading it calls into native code.
This is the shape Design the boundary first recommends: the data stays native, and small values cross.
Run it
Section titled “Run it”The screen shows 5 fixes, 3.55 km, top speed 1.6 m/s.