craft-native 0.0.99 → 0.0.100

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.
@@ -730,6 +730,10 @@ export declare const pushNotifications: {
730
730
  export type HealthDataType = 'steps' | 'heartRate' | 'activeEnergy' | 'distance' | 'workouts' | 'restingHeartRate' | 'heartRateVariability' | 'bodyMass' | 'sleep';
731
731
  /** The types with one value per day. `sleep` is hours asleep, counted on the day you woke. */
732
732
  export type HealthDailyType = Exclude<HealthDataType, 'workouts'>;
733
+ export interface HealthAuthorizationOptions {
734
+ /** `false` asks to read only. Default: also allowed to save workouts. */
735
+ write?: boolean;
736
+ }
733
737
  export interface HealthDataOptions {
734
738
  startDate?: number;
735
739
  endDate?: number;
@@ -791,7 +795,12 @@ export interface HealthDailyValue {
791
795
  unit: string;
792
796
  }
793
797
  export declare const health: {
794
- requestAuthorization(types: HealthDataType[]): Promise<boolean>;
798
+ /**
799
+ * Ask for the health data a page needs. `{ write: false }` asks to read
800
+ * only, for an app that never writes back; by default it may also save
801
+ * workouts, energy and distance.
802
+ */
803
+ requestAuthorization(types: HealthDataType[], options?: HealthAuthorizationOptions): Promise<boolean>;
795
804
  getData(type: HealthDataType, options?: HealthDataOptions): Promise<HealthDataResult>;
796
805
  saveWorkout(workout: HealthWorkout): Promise<HealthWorkoutResult>;
797
806
  /** Workouts in Apple Health, newest first. iOS only for now. */
package/dist/cli.js CHANGED
@@ -4619,7 +4619,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
4619
4619
  `);
4620
4620
  }
4621
4621
  // package.json
4622
- var version = "0.0.99";
4622
+ var version = "0.0.100";
4623
4623
 
4624
4624
  // bin/cli.ts
4625
4625
  var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
package/dist/index.cjs CHANGED
@@ -310,7 +310,7 @@ function craftBinaryNotFoundMessage(triedPath) {
310
310
  `);
311
311
  }
312
312
  // package.json
313
- var version = "0.0.99";
313
+ var version = "0.0.100";
314
314
 
315
315
  // src/sdk-version.ts
316
316
  var SDK_VERSION = version;
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ function craftBinaryNotFoundMessage(triedPath) {
58
58
  `);
59
59
  }
60
60
  // package.json
61
- var version = "0.0.99";
61
+ var version = "0.0.100";
62
62
 
63
63
  // src/sdk-version.ts
64
64
  var SDK_VERSION = version;
@@ -19,6 +19,8 @@ export interface CraftConfig {
19
19
  backgroundColor?: string;
20
20
  /** The launch and webview background while the phone is in Dark Mode. */
21
21
  backgroundColorDark?: string;
22
+ /** Edge-swipe back and forward through the page's history, pushState entries included. */
23
+ swipeNavigation?: boolean;
22
24
  enableSpeechRecognition?: boolean;
23
25
  enableHaptics?: boolean;
24
26
  enableShare?: boolean;
@@ -359,6 +359,8 @@ struct CraftConfig: Codable {
359
359
  var backgroundColor: String = "#1a1a2e"
360
360
  /// The background while the phone is in Dark Mode; the light one if unset.
361
361
  var backgroundColorDark: String? = nil
362
+ /// Edge-swipe back and forward through the page's history.
363
+ var swipeNavigation: Bool? = nil
362
364
  var enableSpeechRecognition: Bool = false
363
365
  var enableHaptics: Bool = false
364
366
  var enableShare: Bool = false
@@ -530,6 +532,13 @@ struct CraftWebView: UIViewRepresentable {
530
532
  let webView = WKWebView(frame: .zero, configuration: webConfig)
531
533
  webView.navigationDelegate = context.coordinator
532
534
  webView.isOpaque = false
535
+ // An edge swipe goes back (and forward) through the page's history,
536
+ // pushState entries included, the way every iOS app's stack does.
537
+ webView.allowsBackForwardNavigationGestures = config.swipeNavigation ?? false
538
+ #if DEBUG
539
+ // Safari's Develop menu can attach to a debug build; never a release.
540
+ if #available(iOS 16.4, *) { webView.isInspectable = true }
541
+ #endif
533
542
 
534
543
  // Before any message can be offered. Zig evaluates every reply against
535
544
  // this webview, and without it an action would run, succeed, and reach
@@ -1301,7 +1310,7 @@ struct CraftWebView: UIViewRepresentable {
1301
1310
  case "requestHealthAuthorization":
1302
1311
  if config.enableHealthKit {
1303
1312
  let types = body["types"] as? [String] ?? []
1304
- requestHealthAuthorization(types: types, callbackId: callbackId)
1313
+ requestHealthAuthorization(types: types, readOnly: body["readOnly"] as? Bool ?? false, callbackId: callbackId)
1305
1314
  } else {
1306
1315
  rejectCallback(callbackId, error: "HealthKit is disabled", code: "CAPABILITY_DISABLED")
1307
1316
  }
@@ -3239,19 +3248,28 @@ struct CraftWebView: UIViewRepresentable {
3239
3248
  var legacyNotifications = craft.notifications;
3240
3249
 
3241
3250
  craft.contractVersion = '1.0.0';
3251
+ // Actions answered by a person, through a system sheet they
3252
+ // may take a minute to read. Thirty seconds of reading the
3253
+ // HealthKit sheet used to fail the call while the sheet was
3254
+ // still open; these wait for the answer instead.
3255
+ var personFacing = {
3256
+ requestHealthAuthorization: true,
3257
+ requestPermission: true,
3258
+ signInWithApple: true
3259
+ };
3242
3260
  craft._invoke = function(action, payload) {
3243
3261
  var self = craft;
3244
3262
  var id = 'cb_' + (++self._callbackId);
3245
3263
  var message = Object.assign({}, payload || {}, {action: action, callbackId: id});
3246
3264
  window.webkit.messageHandlers.craft.postMessage(message);
3247
3265
  return new Promise(function(resolve, reject) {
3248
- var timeout = setTimeout(function() {
3266
+ var timeout = personFacing[action] ? null : setTimeout(function() {
3249
3267
  delete self._callbacks[id];
3250
3268
  reject(new Error('Craft bridge timed out: ' + action));
3251
3269
  }, 30000);
3252
3270
  self._callbacks[id] = {
3253
- resolve: function(value) { clearTimeout(timeout); resolve(value); },
3254
- reject: function(error) { clearTimeout(timeout); reject(error); }
3271
+ resolve: function(value) { if (timeout) clearTimeout(timeout); resolve(value); },
3272
+ reject: function(error) { if (timeout) clearTimeout(timeout); reject(error); }
3255
3273
  };
3256
3274
  });
3257
3275
  };
@@ -3387,7 +3405,9 @@ struct CraftWebView: UIViewRepresentable {
3387
3405
  readRecording: function() { return craft._invoke('readLocationRecording'); }
3388
3406
  };
3389
3407
  craft.health = {
3390
- requestAuthorization: function(types) { return craft._invoke('requestHealthAuthorization', {types: types || []}); },
3408
+ requestAuthorization: function(types, options) {
3409
+ return craft._invoke('requestHealthAuthorization', {types: types || [], readOnly: Boolean(options && options.write === false)});
3410
+ },
3391
3411
  getData: function(type, options) {
3392
3412
  options = options || {};
3393
3413
  return craft._invoke('getHealthData', {type: type, startDate: options.startDate, endDate: options.endDate});
@@ -5125,7 +5145,7 @@ struct CraftWebView: UIViewRepresentable {
5125
5145
  }
5126
5146
 
5127
5147
  // MARK: - Health
5128
- private func requestHealthAuthorization(types: [String], callbackId: String?) {
5148
+ private func requestHealthAuthorization(types: [String], readOnly: Bool = false, callbackId: String?) {
5129
5149
  guard let healthStore = healthStore else {
5130
5150
  rejectCallback(callbackId, error: "HealthKit not available")
5131
5151
  return
@@ -5188,6 +5208,9 @@ struct CraftWebView: UIViewRepresentable {
5188
5208
  }
5189
5209
  }
5190
5210
 
5211
+ // A page that only reads asks only to read: the sheet then says
5212
+ // "access", not "access and update".
5213
+ if readOnly { shareTypes.removeAll() }
5191
5214
  healthStore.requestAuthorization(toShare: shareTypes, read: readTypes) { [weak self] success, error in
5192
5215
  if success {
5193
5216
  self?.resolveCallback(callbackId, result: true)
package/dist/mobile.js CHANGED
@@ -657,11 +657,11 @@ var pushNotifications = {
657
657
  }
658
658
  };
659
659
  var health = {
660
- async requestAuthorization(types) {
660
+ async requestAuthorization(types, options = {}) {
661
661
  const craft = getCraftRoot();
662
662
  if (!craft?.health?.requestAuthorization)
663
663
  throw new Error("Health data is unavailable");
664
- return Boolean(await craft.health.requestAuthorization(types));
664
+ return Boolean(await craft.health.requestAuthorization(types, options));
665
665
  },
666
666
  async getData(type, options = {}) {
667
667
  const craft = getCraftRoot();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craft-native",
3
- "version": "0.0.99",
3
+ "version": "0.0.100",
4
4
  "type": "module",
5
5
  "description": "Build desktop apps with web languages - TypeScript SDK for Craft",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",