on master help sign in
Fix message delivery: correct timestamp units and defer acknowledgments
ab2cbb5iko
client/App.fs+36−16
@@ -81,7 +81,7 @@ module App =
81 | SendFailed of string
81 | SendFailed of string
82 | SendOk
82 | SendOk
83 | DoSaveContact
83 | DoSaveContact
84− | PollResult of events: IncomingEvent list * status: PollStatus * cursor: int64
84+ | PollResult of events: IncomingEvent list * ackIds: string list * status: PollStatus * cursor: int64
85 | CopyPubKey
85 | CopyPubKey
86 | DismissError
86 | DismissError
87 | StateLoaded of StateLoadResult
87 | StateLoaded of StateLoadResult
@@ -95,6 +95,7 @@ module App =
95 | CmdConnect of url: string * identity: Identity
95 | CmdConnect of url: string * identity: Identity
96 | CmdSend of session: Session * recipientHex: string * text: string * messageId: string
96 | CmdSend of session: Session * recipientHex: string * text: string * messageId: string
97 | CmdPoll of session: Session * cursor: int64
97 | CmdPoll of session: Session * cursor: int64
98+ | CmdAckAndDeliver of session: Session * ackIds: string list * events: IncomingEvent list
98 | CmdCopyToClipboard of string
99 | CmdCopyToClipboard of string
99 | CmdLoadState
100 | CmdLoadState
100 | CmdSaveIdentity of Identity
101 | CmdSaveIdentity of Identity
@@ -154,7 +155,7 @@ module App =
154 match evt.Envelope with
155 match evt.Envelope with
155 | Envelope.TextMessage(id, body) ->
156 | Envelope.TextMessage(id, body) ->
156 let message =
157 let message =
157− { Id = id; Body = body; Timestamp = DateTimeOffset.FromUnixTimeSeconds(evt.Timestamp)
158+ { Id = id; Body = body; Timestamp = DateTimeOffset.FromUnixTimeMilliseconds(evt.Timestamp)
158 IsOutgoing = false; Status = DeliveryStatus.Delivered }
159 IsOutgoing = false; Status = DeliveryStatus.Delivered }
159 { m with
160 { m with
160 Contacts =
161 Contacts =
@@ -221,7 +222,7 @@ module App =
221 match model.Auth with
222 match model.Auth with
222 | Identified(id, Connecting) ->
223 | Identified(id, Connecting) ->
223 let session = { Url = model.ServerUrl; Token = token; Identity = id }
224 let session = { Url = model.ServerUrl; Token = token; Identity = id }
224− { model with Auth = Identified(id, Online token); Page = Conversations; Error = None },
225+ { model with Auth = Identified(id, Online token); Page = Conversations; Error = None; PollStatus = Polling },
225 [ CmdPoll(session, model.PollCursor) ]
226 [ CmdPoll(session, model.PollCursor) ]
226 | _ -> model, []
227 | _ -> model, []
227
228
@@ -258,12 +259,15 @@ module App =
258 | SendFailed err -> { model with Error = Some err }, []
259 | SendFailed err -> { model with Error = Some err }, []
259 | SendOk -> model, []
260 | SendOk -> model, []
260
261
261− | PollResult(events, status, newCursor) ->
262+ | PollResult(events, ackIds, status, newCursor) ->
262 let model' = events |> List.fold applyEvent { model with PollStatus = status; PollCursor = newCursor }
263 let model' = events |> List.fold applyEvent { model with PollStatus = status; PollCursor = newCursor }
263
264
264 model',
265 model',
265 [ match trySession model' with
266 [ match trySession model' with
267+ | Some session ->
268+ if not ackIds.IsEmpty || not events.IsEmpty then
269+ CmdAckAndDeliver(session, ackIds, events)
266− | Some session -> CmdPoll(session, model'.PollCursor)
270+ CmdPoll(session, model'.PollCursor)
267 | None -> ()
271 | None -> ()
268 if not events.IsEmpty then saveCmdMsg model' ]
272 if not events.IsEmpty then saveCmdMsg model' ]
269
273
@@ -329,6 +333,8 @@ module App =
329
333
330 // ── mapCmd ──
334 // ── mapCmd ──
331
335
336+ let private log msg = eprintfn $"[skrepka] {msg}"
337+
332 let private asyncCmd (op: Async<Msg>) : Cmd<Msg> =
338 let private asyncCmd (op: Async<Msg>) : Cmd<Msg> =
333 Cmd.ofEffect (fun dispatch ->
339 Cmd.ofEffect (fun dispatch ->
334 async {
340 async {
@@ -343,13 +349,13 @@ module App =
343 | Envelope.DeliveryAck ackIds ->
349 | Envelope.DeliveryAck ackIds ->
344 JsonSerializer.Serialize({| ``type`` = "delivery.ack"; id = Guid.NewGuid().ToString(); ack_ids = ackIds |})
350 JsonSerializer.Serialize({| ``type`` = "delivery.ack"; id = Guid.NewGuid().ToString(); ack_ids = ackIds |})
345 | Envelope.ProfileMessage profile ->
351 | Envelope.ProfileMessage profile ->
346− JsonSerializer.Serialize({| ``type`` = "profile"; id = Guid.NewGuid().ToString(); timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); display_name = profile.DisplayName; bio = profile.Bio; photo = profile.PhotoBase64 |})
352+ JsonSerializer.Serialize({| ``type`` = "profile"; id = Guid.NewGuid().ToString(); timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); display_name = profile.DisplayName; bio = profile.Bio; photo = profile.PhotoBase64 |})
347
353
348 let private sendEnvelope (session: Session) (recipientHex: string) (envelope: Envelope) =
354 let private sendEnvelope (session: Session) (recipientHex: string) (envelope: Envelope) =
349 async {
355 async {
350 let payload = serializeEnvelope envelope
356 let payload = serializeEnvelope envelope
351 let blob = Crypto.encrypt session.Identity.PrivKey (Crypto.fromHex recipientHex) payload
357 let blob = Crypto.encrypt session.Identity.PrivKey (Crypto.fromHex recipientHex) payload
352− let ts = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
358+ let ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
353 do! sendMessage session.Url session.Token recipientHex (Crypto.toHex blob) ts
359 do! sendMessage session.Url session.Token recipientHex (Crypto.toHex blob) ts
354 }
360 }
355
361
@@ -421,8 +427,11 @@ module App =
421
427
422 | CmdPoll(session, cursor) ->
428 | CmdPoll(session, cursor) ->
423 asyncCmd (async {
429 asyncCmd (async {
430+ log $"poll start cursor={cursor}"
424 try
431 try
425 let! response = poll session.Url session.Token cursor
432 let! response = poll session.Url session.Token cursor
433+ log $"poll response: {response.Events.Length} events, cursor={response.Cursor}"
434+
426 let ackIds = response.Events |> Array.map _.Id |> Array.toList
435 let ackIds = response.Events |> Array.map _.Id |> Array.toList
427
436
428 let results =
437 let results =
@@ -430,30 +439,40 @@ module App =
430 |> Array.choose (fun evt ->
439 |> Array.choose (fun evt ->
431 match evt.EventType with
440 match evt.EventType with
432 | Message -> Some(decryptEvent session.Identity.PrivKey evt.Payload)
441 | Message -> Some(decryptEvent session.Identity.PrivKey evt.Payload)
433− | UnknownEvent _ -> None)
442+ | UnknownEvent s -> log $"unknown event type: {s}"; None)
434
443
435 let events = results |> Array.choose Result.toOption |> Array.toList
444 let events = results |> Array.choose Result.toOption |> Array.toList
436 let errors = results |> Array.choose (function Error e -> Some e | _ -> None) |> Array.toList
445 let errors = results |> Array.choose (function Error e -> Some e | _ -> None) |> Array.toList
437
446
438− if not ackIds.IsEmpty then
447+ for e in errors do log $"decrypt error: {e}"
439− try do! ackMessages session.Url session.Token ackIds
440− with _ -> ()
441
448
442− do! sendDeliveryAcks session events
449+ if response.Events.Length = 0 then
450+ do! Async.Sleep 5000
443
451
444 let chatCount = events |> List.sumBy (fun e -> match e.Envelope with Envelope.TextMessage _ -> 1 | _ -> 0)
452 let chatCount = events |> List.sumBy (fun e -> match e.Envelope with Envelope.TextMessage _ -> 1 | _ -> 0)
445 let status =
453 let status =
446 $"evts:{response.Events.Length} msgs:{chatCount} errs:{errors.Length}"
454 $"evts:{response.Events.Length} msgs:{chatCount} errs:{errors.Length}"
447 + (match List.tryHead errors with Some e -> $" [{e}]" | None -> "")
455 + (match List.tryHead errors with Some e -> $" [{e}]" | None -> "")
448− return PollResult(events, Received status, response.Cursor)
456+ return PollResult(events, ackIds, Received status, response.Cursor)
449 with
457 with
450 | :? TimeoutException ->
458 | :? TimeoutException ->
459+ log "poll timeout"
451− return PollResult([], Polling, cursor)
460+ return PollResult([], [], Polling, cursor)
452 | ex ->
461 | ex ->
462+ log $"poll error: {ex.Message}"
453 do! Async.Sleep 3000
463 do! Async.Sleep 3000
454− return PollResult([], PollError ex.Message, cursor)
464+ return PollResult([], [], PollError ex.Message, cursor)
455 })
465 })
456
466
467+ | CmdAckAndDeliver(session, ackIds, events) ->
468+ Cmd.ofEffect (fun _ ->
469+ async {
470+ if not ackIds.IsEmpty then
471+ try do! ackMessages session.Url session.Token ackIds
472+ with _ -> ()
473+ do! sendDeliveryAcks session events
474+ } |> Async.Start)
475+
457 | CmdCopyToClipboard text ->
476 | CmdCopyToClipboard text ->
458 Cmd.ofEffect (fun _ ->
477 Cmd.ofEffect (fun _ ->
459 Microsoft.Maui.ApplicationModel.DataTransfer.Clipboard.Default.SetTextAsync(text)
478 Microsoft.Maui.ApplicationModel.DataTransfer.Clipboard.Default.SetTextAsync(text)
@@ -594,7 +613,8 @@ module App =
594 Button("Settings", SetPage Settings)
613 Button("Settings", SetPage Settings)
595 }
614 }
596
615
616+ let pubPrefix = match model.Auth with Identified(id, _) -> id.PubKeyHex.[..7] | _ -> "?"
597− Label($"{connStatusLabel model.Auth} | {formatPollStatus model.PollStatus}")
617+ Label($"{connStatusLabel model.Auth} [{pubPrefix}] | {formatPollStatus model.PollStatus}")
598 .font(size = 10.)
618 .font(size = 10.)
599 .textColor(Colors.DimGray)
619 .textColor(Colors.DimGray)
600
620
client/Skrepka.fsproj+4
@@ -54,6 +54,10 @@
54 <None Include="$(MacCatalystProjectFolder)Info.plist" LogicalName="Info.plist" />
54 <None Include="$(MacCatalystProjectFolder)Info.plist" LogicalName="Info.plist" />
55 <Compile Include="$(MacCatalystProjectFolder)AppDelegate.fs" />
55 <Compile Include="$(MacCatalystProjectFolder)AppDelegate.fs" />
56 <Compile Include="$(MacCatalystProjectFolder)Program.fs" />
56 <Compile Include="$(MacCatalystProjectFolder)Program.fs" />
57+ <NativeReference Include="native/maccatalyst-arm64/libsodium.a">
58+ <Kind>Static</Kind>
59+ <ForceLoad>true</ForceLoad>
60+ </NativeReference>
57 </ItemGroup>
61 </ItemGroup>
58
62
59 <ItemGroup>
63 <ItemGroup>
client/Store.fs+14−7
@@ -61,11 +61,11 @@ module Store =
61 let private orEmpty s = s |> Option.ofObj |> Option.defaultValue ""
61 let private orEmpty s = s |> Option.ofObj |> Option.defaultValue ""
62
62
63 let private toChatMessage (d: MessageDoc) : ChatMessage =
63 let private toChatMessage (d: MessageDoc) : ChatMessage =
64− { Id = d.Id; Body = d.Body; Timestamp = DateTimeOffset.FromUnixTimeSeconds d.TimestampUnix; IsOutgoing = d.IsOutgoing
64+ { Id = d.Id; Body = d.Body; Timestamp = DateTimeOffset.FromUnixTimeMilliseconds d.TimestampUnix; IsOutgoing = d.IsOutgoing
65 Status = match d.Status with 1 -> DeliveryStatus.Delivered | _ -> DeliveryStatus.Sent }
65 Status = match d.Status with 1 -> DeliveryStatus.Delivered | _ -> DeliveryStatus.Sent }
66
66
67 let private toMessageDoc convId (m: ChatMessage) : MessageDoc =
67 let private toMessageDoc convId (m: ChatMessage) : MessageDoc =
68− { Id = m.Id; ConversationId = convId; Body = m.Body; TimestampUnix = m.Timestamp.ToUnixTimeSeconds(); IsOutgoing = m.IsOutgoing
68+ { Id = m.Id; ConversationId = convId; Body = m.Body; TimestampUnix = m.Timestamp.ToUnixTimeMilliseconds(); IsOutgoing = m.IsOutgoing
69 Status = match m.Status with DeliveryStatus.Delivered -> 1 | DeliveryStatus.Sent -> 0 }
69 Status = match m.Status with DeliveryStatus.Delivered -> 1 | DeliveryStatus.Sent -> 0 }
70
70
71 let private openDb () =
71 let private openDb () =
@@ -73,9 +73,11 @@ module Store =
73
73
74 let loadIdentity () =
74 let loadIdentity () =
75 async {
75 async {
76− let! privKeyB64 =
76+ let privKeyB64 =
77+ try
77− SecureStorage.Default.GetAsync("identity_privkey")
78+ SecureStorage.Default.GetAsync("identity_privkey").Result
78− |> Async.AwaitTask
79+ with _ ->
80+ Preferences.Default.Get<string>("identity_privkey", null)
79
81
80 return
82 return
81 privKeyB64
83 privKeyB64
@@ -84,8 +86,13 @@ module Store =
84 }
86 }
85
87
86 let saveIdentity (identity: Crypto.Identity) =
88 let saveIdentity (identity: Crypto.Identity) =
89+ async {
87− SecureStorage.Default.SetAsync("identity_privkey", Convert.ToBase64String identity.PrivKey)
90+ let b64 = Convert.ToBase64String identity.PrivKey
88− |> Async.AwaitTask
91+ try
92+ do! SecureStorage.Default.SetAsync("identity_privkey", b64) |> Async.AwaitTask
93+ with _ ->
94+ Preferences.Default.Set("identity_privkey", b64)
95+ }
89
96
90 let loadProfile () : Profile option =
97 let loadProfile () : Profile option =
91 try
98 try
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/_CodeSignature/CodeResources+4−4
@@ -166,11 +166,11 @@
166 </data>
166 </data>
167 <key>Skrepka.dll</key>
167 <key>Skrepka.dll</key>
168 <data>
168 <data>
169− aXUF2yqciArDUpIG8FWUZMDCA1I=
169+ s8PyPwCSNW5n4mLoKbZRYZCdBlQ=
170 </data>
170 </data>
171 <key>Skrepka.pdb</key>
171 <key>Skrepka.pdb</key>
172 <data>
172 <data>
173− 0n3E0Wq5iRv4YZ97OD9CsFBxP7w=
173+ a3E89uVnbY/Utk+yFVM2Lm/t6M4=
174 </data>
174 </data>
175 <key>Sodium.Core.dll</key>
175 <key>Sodium.Core.dll</key>
176 <data>
176 <data>
@@ -1393,14 +1393,14 @@
1393 <dict>
1393 <dict>
1394 <key>hash2</key>
1394 <key>hash2</key>
1395 <data>
1395 <data>
1396− UGHZWuVltZrNwVaYJ/N9owIgazB1eG0KCdfWAzXXaeg=
1396+ BnNp/p3G9P1OwGp1sytqKQZmoSHqPOpHBozEXJeLvL8=
1397 </data>
1397 </data>
1398 </dict>
1398 </dict>
1399 <key>Skrepka.pdb</key>
1399 <key>Skrepka.pdb</key>
1400 <dict>
1400 <dict>
1401 <key>hash2</key>
1401 <key>hash2</key>
1402 <data>
1402 <data>
1403− UpSY8oED9rpyHBTZgMHBlVoUdZJQYv8rFhpAlYw8uxk=
1403+ ECnTzLDTEzxOijmAKfSRHGinbYDp0uCvHgxV38eaRxs=
1404 </data>
1404 </data>
1405 </dict>
1405 </dict>
1406 <key>Sodium.Core.dll</key>
1406 <key>Sodium.Core.dll</key>
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/NativeLink.cache+1−1
@@ -1 +1 @@
1−12e8ce10c5be9e5289c58b8051e2bffc33b57e85c27f5e6cada36a811eac4be4
1+1af14896b927eee2f53f99fd05e19ebb83adf0fdebf097f41e0305a8d7c98c7b
client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/NativeLink.cache.uptodate+1−1
@@ -1 +1 @@
1−12e8ce10c5be9e5289c58b8051e2bffc33b57e85c27f5e6cada36a811eac4be4
1+1af14896b927eee2f53f99fd05e19ebb83adf0fdebf097f41e0305a8d7c98c7b
client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/_CodeSignature/CodeResources+2−2
@@ -251,14 +251,14 @@
251 <dict>
251 <dict>
252 <key>hash2</key>
252 <key>hash2</key>
253 <data>
253 <data>
254− 3LcdsLfdVYuDBW0ymTQh3rdGiQHcuX7ODuir5wWC31E=
254+ ypBM+bfWTNP3ypf/qWbairU8KROoUpHhZHHeZjByNcY=
255 </data>
255 </data>
256 </dict>
256 </dict>
257 <key>MonoBundle/Skrepka.pdb</key>
257 <key>MonoBundle/Skrepka.pdb</key>
258 <dict>
258 <dict>
259 <key>hash2</key>
259 <key>hash2</key>
260 <data>
260 <data>
261− lRWXRbB8uj3FbCIrO8gezrJOD9pFheKChVU0l3hAUww=
261+ ATYHW4k25Jaa72t5xcRmdNXWHA/0w2ny+PJ2Mhu7otM=
262 </data>
262 </data>
263 </dict>
263 </dict>
264 <key>MonoBundle/Sodium.Core.dll</key>
264 <key>MonoBundle/Sodium.Core.dll</key>
client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/native/maccatalyst-arm64/libsodium.anew file

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+13fba34bce3f96385873f0ca187ae06eb3948ede")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+5df6e95df9ea5612efd197a45f76769b5039dc65")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−4c5fb9e930282efdfc08d13cf8523ae2e9407e25f7ae4d0f31c1a689a8d11501
1+f21e5289d353238b61edffd7af2a97457c64ee213f0152b0b8dda0cd8c6bc8e3
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.fsproj.FileListAbsolute.txt−23
@@ -334,26 +334,3 @@
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
337−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.stamp
338−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.MauiControls.stamp
339−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/FSharp.Core.stamp
340−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/LiteDB.stamp
341−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.Abstractions.stamp
342−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.stamp
343−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.Abstractions.stamp
344−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.stamp
345−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Diagnostics.Abstractions.stamp
346−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.FileProviders.Abstractions.stamp
347−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Hosting.Abstractions.stamp
348−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.Abstractions.stamp
349−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.stamp
350−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Options.stamp
351−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Primitives.stamp
352−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Compatibility.stamp
353−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.stamp
354−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Xaml.stamp
355−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.stamp
356−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Essentials.stamp
357−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Graphics.stamp
358−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Sodium.Core.stamp
359−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/unpack/Microsoft.Maui.Essentials/BundleResource/xml/microsoft_maui_essentials_fileprovider_file_paths.xml
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/13fba34bce3f96385873f0ca187ae06eb3948ede/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/5df6e95df9ea5612efd197a45f76769b5039dc65/*"}}
client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/refint/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+13fba34bce3f96385873f0ca187ae06eb3948ede")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+5df6e95df9ea5612efd197a45f76769b5039dc65")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−bf686c8aa53e2b74b728dc8168a09d41edb321c94ecbe8bf4e3e21c20a8edd68
1+ce2a46a6bcc0c8aa17bed684b2657f9621a34bc9674677f9c42338c570be5346
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/13fba34bce3f96385873f0ca187ae06eb3948ede/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/5df6e95df9ea5612efd197a45f76769b5039dc65/*"}}
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/refint/Skrepka.dll

Binary file not shown.