@tokamakdev/platform-ios-arm64 0.1.1-beta.50 → 0.1.1-beta.52

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.
@@ -11,12 +11,6 @@ enum {
11
11
  TOKAMAK_DECISION_USE = 2,
12
12
  };
13
13
 
14
- enum {
15
- TOKAMAK_DISPATCH_HANDLED = 0,
16
- TOKAMAK_DISPATCH_UNHANDLED = 1,
17
- TOKAMAK_DISPATCH_FAILED = 2,
18
- };
19
-
20
14
  typedef struct {
21
15
  uint8_t *data;
22
16
  size_t len;
@@ -28,7 +22,8 @@ typedef struct {
28
22
  } TokamakIdentity;
29
23
 
30
24
  void *tokamak_runtime_start(const char *packaged_dir, const char *state_dir,
31
- const char *host, char *error, size_t error_len);
25
+ const char *storage_dir, const char *host,
26
+ char *error, size_t error_len);
32
27
  void *tokamak_runtime_start_development(const char *state_dir, const char *host,
33
28
  const char *endpoint,
34
29
  const char *session_token, char *error,
@@ -39,10 +34,10 @@ uint16_t tokamak_runtime_restore_gateway(const void *runtime, char *error,
39
34
  bool tokamak_runtime_suspend(const void *runtime);
40
35
  bool tokamak_runtime_resume(const void *runtime);
41
36
  void tokamak_runtime_stop(void *runtime);
42
- int32_t tokamak_runtime_dispatch(const void *runtime, const char *event,
43
- const char *payload, uint64_t timeout_ms,
44
- TokamakBytes *result, char *error,
45
- size_t error_len);
37
+ bool tokamak_runtime_call(const void *runtime, const char *name,
38
+ const char *body, uint64_t timeout_ms,
39
+ TokamakBytes *response, char *error,
40
+ size_t error_len);
46
41
 
47
42
  int32_t tokamak_runtime_server_authority(const void *runtime, const char *host,
48
43
  TokamakBytes *authority);
@@ -32,15 +32,15 @@ final class TokamakHost {
32
32
  }
33
33
  }
34
34
 
35
- /// Runs the Worker's `event` handler with a JSON-serialisable `payload`,
36
- /// including work it passes to `ctx.waitUntil`, and stops it after
37
- /// `timeout`. Call it on the main thread; `completion` runs on the main
38
- /// thread.
39
- func dispatch(
40
- event: String,
41
- payload: Any,
35
+ /// Posts `body`, JSON-serialisable, to the Worker's `/tokamak/<name>`
36
+ /// endpoint and returns the response body. Fails unless the Worker responds
37
+ /// 200 within `timeout`. Call it on the main thread; `completion` runs on
38
+ /// the main thread.
39
+ func call(
40
+ _ name: String,
41
+ body: Any,
42
42
  timeout: TimeInterval,
43
- completion: @escaping (Result<TokamakEventOutcome, Error>) -> Void
43
+ completion: @escaping (Result<Data, Error>) -> Void
44
44
  ) {
45
45
  whenStarted { result in
46
46
  switch result {
@@ -48,9 +48,7 @@ final class TokamakHost {
48
48
  completion(.failure(error))
49
49
  case .success(let runtime):
50
50
  DispatchQueue.global(qos: .userInitiated).async {
51
- let outcome = Result {
52
- try runtime.dispatch(event: event, payload: payload, timeout: timeout)
53
- }
51
+ let outcome = Result { try runtime.call(name, body: body, timeout: timeout) }
54
52
  DispatchQueue.main.async { completion(outcome) }
55
53
  }
56
54
  }
@@ -104,14 +102,6 @@ final class TokamakHost {
104
102
  }
105
103
  }
106
104
 
107
- /// What a Worker event handler did.
108
- enum TokamakEventOutcome {
109
- /// The handler's result, decoded from JSON; `NSNull` when it returned nothing.
110
- case handled(Any)
111
- /// The Worker has no handler for the event.
112
- case unhandled
113
- }
114
-
115
105
  /// What a plugin did with a background event, reported to the system.
116
106
  enum TokamakBackgroundResult {
117
107
  case newData
@@ -192,17 +182,21 @@ final class RuntimeHandle {
192
182
  guard let bundle else {
193
183
  throw RuntimeError.configuration("app bundle resources are unavailable")
194
184
  }
185
+ let storage = try Self.storageDirectory()
195
186
  handle = bundle.path.withCString { bundlePath in
196
187
  state.path.withCString { statePath in
197
- appHost.withCString { appHost in
198
- error.withUnsafeMutableBufferPointer { error in
199
- tokamak_runtime_start(
200
- bundlePath,
201
- statePath,
202
- appHost,
203
- error.baseAddress,
204
- error.count
205
- )
188
+ storage.path.withCString { storagePath in
189
+ appHost.withCString { appHost in
190
+ error.withUnsafeMutableBufferPointer { error in
191
+ tokamak_runtime_start(
192
+ bundlePath,
193
+ statePath,
194
+ storagePath,
195
+ appHost,
196
+ error.baseAddress,
197
+ error.count
198
+ )
199
+ }
206
200
  }
207
201
  }
208
202
  }
@@ -241,49 +235,39 @@ final class RuntimeHandle {
241
235
  return port
242
236
  }
243
237
 
244
- /// Runs the Worker's `event` handler, blocking until it settles or
245
- /// `timeout` passes.
246
- func dispatch(event: String, payload: Any, timeout: TimeInterval) throws -> TokamakEventOutcome {
247
- guard JSONSerialization.isValidJSONObject([payload]) else {
248
- throw RuntimeError.runtime("the \(event) payload is not JSON")
238
+ /// Posts `body` to the Worker's `/tokamak/<name>` endpoint, blocking until
239
+ /// it responds 200 or `timeout` passes.
240
+ func call(_ name: String, body: Any, timeout: TimeInterval) throws -> Data {
241
+ guard JSONSerialization.isValidJSONObject([body]) else {
242
+ throw RuntimeError.runtime("the \(name) call body is not JSON")
249
243
  }
250
- let payload = String(
251
- decoding: try JSONSerialization.data(withJSONObject: payload, options: .fragmentsAllowed),
244
+ let body = String(
245
+ decoding: try JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed),
252
246
  as: UTF8.self
253
247
  )
254
- var result = TokamakBytes(data: nil, len: 0)
248
+ var response = TokamakBytes(data: nil, len: 0)
255
249
  var error = [CChar](repeating: 0, count: 1024)
256
- let status = event.withCString { event in
257
- payload.withCString { payload in
250
+ let succeeded = name.withCString { name in
251
+ body.withCString { body in
258
252
  error.withUnsafeMutableBufferPointer { error in
259
- tokamak_runtime_dispatch(
253
+ tokamak_runtime_call(
260
254
  handle,
261
- event,
262
- payload,
255
+ name,
256
+ body,
263
257
  UInt64(timeout * 1000),
264
- &result,
258
+ &response,
265
259
  error.baseAddress,
266
260
  error.count
267
261
  )
268
262
  }
269
263
  }
270
264
  }
271
- defer { tokamak_bytes_free(result) }
272
- switch status {
273
- case Int32(TOKAMAK_DISPATCH_HANDLED):
274
- guard let bytes = result.data else {
275
- throw RuntimeError.runtime("the Worker event result is missing")
276
- }
277
- return .handled(
278
- try JSONSerialization.jsonObject(
279
- with: Data(bytes: bytes, count: result.len),
280
- options: .fragmentsAllowed
281
- ))
282
- case Int32(TOKAMAK_DISPATCH_UNHANDLED):
283
- return .unhandled
284
- default:
265
+ defer { tokamak_bytes_free(response) }
266
+ guard succeeded else {
285
267
  throw RuntimeError.runtime(String(cString: error))
286
268
  }
269
+ guard let bytes = response.data else { return Data() }
270
+ return Data(bytes: bytes, count: response.len)
287
271
  }
288
272
 
289
273
  func serverAuthority(
@@ -352,21 +336,31 @@ final class RuntimeHandle {
352
336
  )
353
337
  }
354
338
 
339
+ /// Stores behind storage bindings, which device backups include.
340
+ private static func storageDirectory() throws -> URL {
341
+ let storage = try appDirectory(.applicationSupportDirectory)
342
+ .appendingPathComponent("tokamak/storage", isDirectory: true)
343
+ try FileManager.default.createDirectory(at: storage, withIntermediateDirectories: true)
344
+ return storage
345
+ }
346
+
355
347
  private static func stateDirectory() throws -> URL {
348
+ let state = try appDirectory(.cachesDirectory)
349
+ try FileManager.default.createDirectory(at: state, withIntermediateDirectories: true)
350
+ return state
351
+ }
352
+
353
+ /// This app's folder in the user's `directory`.
354
+ private static func appDirectory(_ directory: FileManager.SearchPathDirectory) throws -> URL {
356
355
  guard let identifier = Bundle.main.bundleIdentifier else {
357
356
  throw RuntimeError.configuration("CFBundleIdentifier is required")
358
357
  }
359
- let root = try FileManager.default.url(
360
- for: .cachesDirectory,
358
+ return try FileManager.default.url(
359
+ for: directory,
361
360
  in: .userDomainMask,
362
361
  appropriateFor: nil,
363
362
  create: true
364
363
  )
365
- let state = root.appendingPathComponent(identifier, isDirectory: true)
366
- try FileManager.default.createDirectory(
367
- at: state,
368
- withIntermediateDirectories: true
369
- )
370
- return state
364
+ .appendingPathComponent(identifier, isDirectory: true)
371
365
  }
372
366
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamakdev/platform-ios-arm64",
3
- "version": "0.1.1-beta.50",
3
+ "version": "0.1.1-beta.52",
4
4
  "description": "The tokamak platform pack for ios-arm64",
5
5
  "repository": {
6
6
  "type": "git",