on master help sign in
LICENSEnew file+7
since splitsnapshots
unifiedsplit
@@ -0,0 +1,7 @@
1+Copyright 2023 Ilia Kostiuchenko
2+
3+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
README.md+7
@@ -8,8 +8,15 @@
8
8
9[![DEMO](https://img.youtube.com/vi/tynCzifvIzE/0.jpg)](https://www.youtube.com/watch?v=tynCzifvIzE)
9[![DEMO](https://img.youtube.com/vi/tynCzifvIzE/0.jpg)](https://www.youtube.com/watch?v=tynCzifvIzE)
10
10
11+
12+## Getting started
13+
14+The easiest way of using this library is by using the [airlock template](https://github.com/ilyakooo0/airlock-template).
15+
11### FFI
16### FFI
12
17
18+This is for setting up this library from scratch.
19+
13Urbit subscriptions require [server-side event (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).
20Urbit subscriptions require [server-side event (SSE)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events).
14Unfortunately, Elm does not provide a native implementation.
21Unfortunately, Elm does not provide a native implementation.
15This means that we will need to use [JS FFI (aka ports)](https://guide.elm-lang.org/interop/ports.html).
22This means that we will need to use [JS FFI (aka ports)](https://guide.elm-lang.org/interop/ports.html).
elm.json+11−2
@@ -3,9 +3,18 @@
3 "name": "ilyakooo0/airlock",
3 "name": "ilyakooo0/airlock",
4 "summary": "Urbit airlock",
4 "summary": "Urbit airlock",
5 "license": "MIT",
5 "license": "MIT",
6− "version": "1.0.0",
6+ "version": "1.1.1",
7 "exposed-modules": [
7 "exposed-modules": [
8− "Ur", "Ur.Cmd", "Ur.Sub", "Ur.Constructor", "Ur.Deconstructor", "Ur.Phonemic", "Ur.Da", "Ur.Uw", "Ur.Run", "Ur.Types"
8+ "Ur",
9+ "Ur.Cmd",
10+ "Ur.Sub",
11+ "Ur.Constructor",
12+ "Ur.Deconstructor",
13+ "Ur.Phonemic",
14+ "Ur.Da",
15+ "Ur.Uw",
16+ "Ur.Run",
17+ "Ur.Types"
9 ],
18 ],
10 "elm-version": "0.19.0 <= v < 0.20.0",
19 "elm-version": "0.19.0 <= v < 0.20.0",
11 "dependencies": {
20 "dependencies": {
src/BitWriter.elm+5−5
@@ -14,17 +14,17 @@ import Bytes.Encode as BE
14
14
15empty : BitWriter
15empty : BitWriter
16empty =
16empty =
17− BitWriter { running = Nothing, collected = BE.sequence [], offset = 0 }
17+ BitWriter { running = Nothing, collected = [], offset = 0 }
18
18
19
19
20run : BitWriter -> Bytes
20run : BitWriter -> Bytes
21run (BitWriter { running, collected }) =
21run (BitWriter { running, collected }) =
22 case running of
22 case running of
23 Nothing ->
23 Nothing ->
24− BE.encode collected
24+ BE.encode (collected |> List.reverse |> BE.sequence)
25
25
26 Just { value } ->
26 Just { value } ->
27− BE.sequence [ collected, BE.unsignedInt8 value ] |> BE.encode
27+ BE.sequence (BE.unsignedInt8 value :: collected |> List.reverse) |> BE.encode
28
28
29
29
30type BitWriter
30type BitWriter
@@ -35,7 +35,7 @@ type BitWriter
35 , length : Int
35 , length : Int
36 }
36 }
37 , offset : Int
37 , offset : Int
38− , collected : BE.Encoder
38+ , collected : List BE.Encoder
39 }
39 }
40
40
41
41
@@ -68,7 +68,7 @@ bit b (BitWriter { running, collected, offset }) =
68 if length == 7 then
68 if length == 7 then
69 BitWriter
69 BitWriter
70 { running = Nothing
70 { running = Nothing
71− , collected = BE.sequence [ collected, BE.unsignedInt8 newValue ]
71+ , collected = BE.unsignedInt8 newValue :: collected
72 , offset = newOffset
72 , offset = newOffset
73 }
73 }
74
74
src/Ur/Deconstructor.elm+42−3
@@ -6,7 +6,7 @@ module Ur.Deconstructor exposing
6 , int, signedInt, bigint
6 , int, signedInt, bigint
7 , float32, float64
7 , float32, float64
8 , cord, tape
8 , cord, tape
9− , bytes, sig, ignore, tar, lazy
9+ , bytes, sig, ignore, tar, lazy, debug
10 )
10 )
11
11
12{-| This module provides an API to deconstruct `Noun`s into arbitrary Elm data structures.
12{-| This module provides an API to deconstruct `Noun`s into arbitrary Elm data structures.
@@ -55,7 +55,7 @@ You would parse a `[%edit @ cord]` like this:
55
55
56# Miscellaneous
56# Miscellaneous
57
57
58−@docs bytes, sig, ignore, tar, lazy
58+@docs bytes, sig, ignore, tar, lazy, debug
59
59
60-}
60-}
61
61
@@ -66,7 +66,7 @@ import Bytes exposing (Bytes, Endianness(..))
66import Bytes.Decode as BD
66import Bytes.Decode as BD
67import Bytes.Encode as BE
67import Bytes.Encode as BE
68import Bytes.Extra
68import Bytes.Extra
69−import Ur.Jam exposing (cue)
69+import Ur.Jam exposing (cue, isSig)
70import Ur.Types exposing (..)
70import Ur.Types exposing (..)
71
71
72
72
@@ -337,3 +337,42 @@ Always succeeds.
337tar : Deconstructor Noun
337tar : Deconstructor Noun
338tar =
338tar =
339 Just
339 Just
340+
341+
342+{-| Debug a deconstructor.
343+If the deconstructor from the second argument fails then the failed nock will be printed to the console.
344+-}
345+debug : (String -> String) -> Deconstructor a -> Deconstructor a
346+debug log f noun =
347+ case f noun of
348+ Just x ->
349+ Just x
350+
351+ Nothing ->
352+ let
353+ _ =
354+ log (prettyNoun noun)
355+ in
356+ Nothing
357+
358+
359+prettyNoun : Noun -> String
360+prettyNoun noun =
361+ let
362+ go isRhs n =
363+ case n of
364+ Atom a ->
365+ if isSig a then
366+ "~"
367+
368+ else
369+ "@"
370+
371+ Cell ( lhs, rhs ) ->
372+ if isRhs then
373+ go False lhs ++ " " ++ go True rhs
374+
375+ else
376+ "[" ++ go False lhs ++ " " ++ go True rhs ++ "]"
377+ in
378+ go False noun
src/Ur/Requests.elm+1−1
@@ -98,7 +98,7 @@ toNoun eventId req =
98 C.cell (C.cord app) (C.listOf C.cord path)
98 C.cell (C.cord app) (C.listOf C.cord path)
99
99
100 Unsubscribe subId ->
100 Unsubscribe subId ->
101− C.cell (C.cord "usubscribe") <|
101+ C.cell (C.cord "unsubscribe") <|
102 C.cell (C.int eventId) (C.int subId)
102 C.cell (C.int eventId) (C.int subId)
103
103
104 Poke { ship, agent, mark, noun } ->
104 Poke { ship, agent, mark, noun } ->
src/Ur/Run.elm+3−3
@@ -178,7 +178,7 @@ update inp msg model =
178 processUrSubs
178 processUrSubs
179 model.eventId
179 model.eventId
180 model.subscriptions
180 model.subscriptions
181− (inp.urbitSubscriptions model.app |> (\(Ur.Sub.Internal.Sub x) -> x))
181+ (inp.urbitSubscriptions appModel |> (\(Ur.Sub.Internal.Sub x) -> x))
182
182
183 ( eventId_, cmds, urReqs ) =
183 ( eventId_, cmds, urReqs ) =
184 processCmd subsResult.eventId appCmds
184 processCmd subsResult.eventId appCmds
@@ -282,7 +282,7 @@ update inp msg model =
282 ( model, Cmd.none )
282 ( model, Cmd.none )
283
283
284 else
284 else
285− case D.run (D.cell D.ignore (D.cell D.ignore deconstructor) |> D.map (\((), ((), m)) -> m)) rest of
285+ case D.run (D.cell D.ignore (D.cell D.ignore deconstructor) |> D.map (\( (), ( (), m ) ) -> m)) rest of
286 Just subMsg ->
286 Just subMsg ->
287 ( model_, pureCmd (AppMsg subMsg) )
287 ( model_, pureCmd (AppMsg subMsg) )
288
288
@@ -313,7 +313,7 @@ update inp msg model =
313 NeedsActivation ->
313 NeedsActivation ->
314 let
314 let
315 ( eventId, reqs ) =
315 ( eventId, reqs ) =
316− [ Poke { ship = "~zod", agent = "hood", mark = "helm-hi", noun = C.cord "Opening airlock!" } ]
316+ [ Poke { ship = "", agent = "hood", mark = "helm-hi", noun = C.cord "Opening airlock!" } ]
317 |> tag model.eventId
317 |> tag model.eventId
318 in
318 in
319 ( { model | eventId = eventId }
319 ( { model | eventId = eventId }
src/Ur/Uw.elm+7−7
@@ -29,24 +29,24 @@ decode string =
29 -- 0w
29 -- 0w
30 |> List.drop 2
30 |> List.drop 2
31
31
32− go : List Char -> BW.BitWriter -> BW.BitWriter
32+ go : List Char -> List Int -> BW.BitWriter -> BW.BitWriter
33− go cs writer =
33+ go cs append writer =
34 case cs of
34 case cs of
35 [] ->
35 [] ->
36− writer
36+ BW.bits append writer
37
37
38 '.' :: rest ->
38 '.' :: rest ->
39− go rest writer
39+ go rest append writer
40
40
41 c :: rest ->
41 c :: rest ->
42 case Dict.get c charToBits of
42 case Dict.get c charToBits of
43 Just bits ->
43 Just bits ->
44− go rest writer |> BW.bits bits
44+ go rest (bits ++ append) writer
45
45
46 Nothing ->
46 Nothing ->
47− go rest writer
47+ go rest [] writer
48 in
48 in
49− BW.run (go chars BW.empty)
49+ BW.run (go chars [] BW.empty)
50
50
51
51
52{-| -}
52{-| -}