Skip to content

Conversation

@RangerMauve
Copy link
Contributor

No description provided.

@RangerMauve RangerMauve marked this pull request as ready for review December 8, 2025 22:09
@gmaclennan
Copy link
Member

I had a good think about this today, and I think it's much simpler to move all of this into the map server and keep it separate from core, other than sending an actual map share "offer" (I think you've called this MapShareRequest in the code) via RPC. I think the map share offer should be sent over the project creator core (not the "open" RPC channel). The rest of the API can all be HTTP/REST, so the rest of the code can be client-side. Otherwise I'm concerned about a complex inter-tangling of the http server code and the JS API, and the increased API surface area of Core. This also reduces messaging over the IPC channel, moving it to HTTP instead.

Routes for the Map-Sharer (although Map Receiver would use the DELETE route)

  • POST /mapShares { mapId: string }: create a map share, returns MapShare type. Data populated internally by the server (bounds, zoom, estimated size)
  • GET /mapShares/:shareId: get MapShare info for a shareId
  • GET /mapShares/:shareId/events: state change events, including bytesDownloaded for state: 'downloading' events.
  • GET /mapShares/:shareId/download: SMP file for share
  • DELETE /mapShares/:shareId: cancel / delete a map share

Routes for Map Receiver:

  • POST /downloads MapShare: start downloading a map share (or reject). Returns { downloadId: string }
  • GET /downloads/:downloadId: MapShare with current state.
  • GET /downloads/:downloadId/events: state change events, including bytesDownloaded
  • DELETE /downloads/:downloadId: cancel download

On Map-sharer side, frontend:

  1. POST /mapShares to create the share
  2. Call mapeoProject.members.sendMapShare(mapShare)
  3. Listen on /mapShares/:shareId/events
  4. To cancel DELETE /mapShares/:shareId

On Map-sharer side, Core backend:

  1. project.members.sendMapShare(mapShare: MapShare) sends message as extension over project creator core

On Map-receiver side, frontend:

  1. Listen on mapeoProject.on('map-share')
  2. POST /downloads to start downloading or reject
  3. listen on GET /downloads/:downloadId/events for progress
  4. To cancel DELETE /downloads/:shareId

On Map-receiver side, backend:

  1. Listen on project creator core for mapShare extension messages, then emit event map-share

The rest of the backend code will all be in the map server, e.g. in the map server on the receiver, POST /downloads will start a download from GET /mapShares/:mapShareId on the map-sharer, and stream events to any connections to GET /downloads/:downloadId/events

I'd prefer to use SSE (server-sent-events) for this, because it's the most lightweight and simple, however React Native support is pretty poor, and React Native has first-class support for WebSocket, so I'm not so sure.

@RangerMauve
Copy link
Contributor Author

Sure. Shall I get started on the map server code as part of this or do you have that in a separate module or PR already?

@RangerMauve
Copy link
Contributor Author

Should the extension message maybe contain the server URL and public key as well? Or is that going to be hidden within the map share server too?

Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

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

This looks good, just some tweaks to the message schema, plus I think a need for some validation. protobuf will decode missing fields without complaining and return them with defaults (empty string, 0, false), so we should validate that values which are required are non-empty - namely the strings. We should maybe just silently ignore an invalid received map share message? I'm not sure what else we can do with it? We do need to add some kind of Sentry / OpenTelemetry reporting for these kind of errors.

And some tests for those invalid values/messages.

@gmaclennan
Copy link
Member

Would you be able to add declineUrls (array of URLs) to the mapShareExtension?

@RangerMauve
Copy link
Contributor Author

@gmaclennan Made changes

  • Updated fields based on your feedback (created fields, sender device id and name, download/decline URLs)
  • Added validation for share extension
  • Added map-share-error event for detecting failed map share attempts (just logging for now)
  • Added tests for validation of map share extension
  • Validating map share before it's sent down the extension (with bypass for tests)
  • Ignoring map shares from blocked/left members
  • Added e2e tests to check that the share is being received and that validation is happening

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants