elm_history_tools 0.2.0 → 0.3.0
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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 040e25befa828f739530f1dcbe81ba5350cae4b6c06f25fc5a7b5a66da906aed
|
4
|
+
data.tar.gz: ba6f918efeacfd835dde3d7fd350c7933bea913a6b6bc7518784abb15e84d35b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8eace2f01d5e3af2940fa086b57723a33e54c0a2e6f58499186511d0dd9809cf348d248a9aa6d13f219d5bc4fe37bad355c5d3555bdeeb9e8b47b938f096e67c
|
7
|
+
data.tar.gz: 8d503d9254bf9258878591c12e3e59fa5f06bf26d97a68eff5b67fc222b1d9e23dab5eaa85bd77ad11f1bdbcf4869da2736345f95cfec2da0e1d64977253395e
|
data/README.md
CHANGED
@@ -100,89 +100,8 @@ You can then easily loop over this data in Ruby to present a readable internal d
|
|
100
100
|
|
101
101
|
## Elm History Export Format
|
102
102
|
|
103
|
-
|
104
|
-
|
105
|
-
```js
|
106
|
-
{
|
107
|
-
"metadata": {
|
108
|
-
"versions": {"elm": "0.18.0"},
|
109
|
-
"types": {
|
110
|
-
// the Message type used by your program
|
111
|
-
"message": "Message.Message",
|
112
|
-
// all the type aliases defined in your program
|
113
|
-
"aliases": {
|
114
|
-
"Json.Decode.Value": {"args":[],"type":"Json.Encode.Value"},
|
115
|
-
// etc.
|
116
|
-
},
|
117
|
-
// all the union types used in your program
|
118
|
-
"unions": {
|
119
|
-
"Maybe.Maybe": {
|
120
|
-
// what arguments the union type takes
|
121
|
-
"args": ["a"],
|
122
|
-
// what tags/constructors make up that union type and what arguments they take
|
123
|
-
"tags":{
|
124
|
-
"Just": ["a"],
|
125
|
-
"Nothing": []
|
126
|
-
}
|
127
|
-
}
|
128
|
-
}
|
129
|
-
}
|
130
|
-
}
|
131
|
-
// what's happened in user session being exported
|
132
|
-
"history": [
|
133
|
-
// each entry is stored with the contructor and any ordered arguments passed to it
|
134
|
-
{"ctor": "MessageType", "_0": "Arg1", "_02": {"ctor": "AnotherType"}},
|
135
|
-
{"ctor": "AnotherMessageType", "_0": "AnotherArg"},
|
136
|
-
// etc.
|
137
|
-
]
|
138
|
-
}
|
139
|
-
```
|
140
|
-
|
141
|
-
Each entry in the history hash represents an Elm message object -- so
|
142
|
-
|
143
|
-
```js
|
144
|
-
{"ctor": "MessageType", "_0": "Arg1", "_02": {"ctor": "AnotherType"}},
|
145
|
-
```
|
146
|
-
|
147
|
-
represents the Elm message
|
148
|
-
|
149
|
-
```elm
|
150
|
-
-- if type alias SomeType = AnotherType | SomethingElse
|
151
|
-
--
|
152
|
-
-- MessageType String SomeType
|
153
|
-
MessageType "Arg1" AnotherType
|
154
|
-
```
|
155
|
-
|
156
|
-
A few notes:
|
157
|
-
|
158
|
-
**Lists**
|
159
|
-
|
160
|
-
List entries are recursively nested objects whose constructor is `::` (cons).
|
161
|
-
|
162
|
-
As an example, an Elm list of three books (`[{title = "Too Like the Lightning"}, {title = "The Fear of Barbarians"}, {title = "Evicted"}]`) would be represented as:
|
163
|
-
|
164
|
-
```js
|
165
|
-
{
|
166
|
-
"ctor": "::",
|
167
|
-
"_0": {"title": "Too Like the Lightning"},
|
168
|
-
"_1": {
|
169
|
-
"ctor": "::",
|
170
|
-
"_0": {"title": "The Fear of Barbarians"},
|
171
|
-
"_1": {
|
172
|
-
"ctor": "::",
|
173
|
-
"_0": {"title": "Evicted"}
|
174
|
-
}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
```
|
178
|
-
|
179
|
-
This is because in Elm, `List` is implemented as a linked list (each element is an object that both stores its value and points to the next element in the list, rather than sitting in an array of plain values).
|
180
|
-
|
181
|
-
You don't need to know anything about linked lists to use Elm (or Javascript or Ruby or, likely, whatever you're using for work or fun -- I've literally never used them in my career), but if you're curious, you can read more about them [on Wikipedia](https://en.wikipedia.org/wiki/Linked_list). You can also check out [this interesting discussion](https://github.com/elm-lang/elm-plans/issues/13) of Arrays vs. Lists in Elm.
|
182
|
-
|
183
|
-
**In the future**
|
184
|
-
|
185
|
-
It looks like the terms will change somewhat in a future version of Elm: `"ctor"` and `"_01"`, `"_02"`, etc. will be [replaced with `$`, `a`, `b`, etc](https://github.com/elm-lang/virtual-dom/commit/61cf2090ecb745542532dd7ea87de37c6ed6c3b4#diff-25d902c24283ab8cfbac54dfa101ad31). ElmHistoryTools will support both formats in the future; should the structure change, obviously that will be addressed too.
|
103
|
+
For more information on the Elm history export format, see [this blog
|
104
|
+
post](https://medium.com/@arsduo/understanding-an-elm-0-19-history-export-1bca38613840).
|
186
105
|
|
187
106
|
**Why hashes?**
|
188
107
|
|
@@ -2,35 +2,35 @@ module ElmHistoryTools::HistoryFormatter
|
|
2
2
|
# Given a raw Elm history file parsed to JSON, return a simplified hash of the history.
|
3
3
|
#
|
4
4
|
# For instance, given an array like:
|
5
|
-
# [{"
|
5
|
+
# [{"$": "MessageType", "a": "Arg1", "a2": {"$": "AnotherType"}}]
|
6
6
|
#
|
7
7
|
# you'll get
|
8
8
|
#
|
9
9
|
# [{"MessageType" => ["Arg1", {"AnotherType" => []}]}]
|
10
10
|
#
|
11
11
|
def self.to_simple_hash(history_data)
|
12
|
-
history_data
|
12
|
+
history_data.dig("a", "history").map do |entry|
|
13
13
|
simplify_history_entry(entry)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
# Turn an Elm history entry into a simple Ruby hash, as described above.
|
18
18
|
#
|
19
|
-
#
|
19
|
+
# Constru$s that take no arguments are represented as taking an empty list (see above); an
|
20
20
|
# alternative approach would be to use nil. While that would clearly distinguish between those
|
21
21
|
# cases, it would make working with the results more complicated.
|
22
22
|
def self.simplify_history_entry(entry)
|
23
23
|
ElmHistoryTools::Utils.transform_object(entry) do |object_hash|
|
24
|
-
if object_hash["
|
25
|
-
# Elm lists are represented as nested entries with the
|
24
|
+
if object_hash["$"] == "::"
|
25
|
+
# Elm lists are represented as nested entries with the contru$ ::. (See the readme for
|
26
26
|
# more detail.)
|
27
27
|
# We collapse those into a proper Ruby array via flatten.
|
28
28
|
# The last entry of the list will have no nested entry, so we use compact to remove the nil.
|
29
|
-
[simplify_history_entry(object_hash["
|
30
|
-
elsif object_hash["
|
29
|
+
[simplify_history_entry(object_hash["a"]), simplify_history_entry(object_hash["b"])].compact.flatten
|
30
|
+
elsif object_hash["$"]
|
31
31
|
# we have an Elm object type (we know this because non-objects aren't passed to the block)
|
32
32
|
{
|
33
|
-
object_hash["
|
33
|
+
object_hash["$"] => object_hash.reject {|k, _v| k == "$"}.values.map {|val| simplify_history_entry(val) }
|
34
34
|
}
|
35
35
|
end
|
36
36
|
end
|
@@ -20,21 +20,23 @@ module ElmHistoryTools::HistorySanitizer
|
|
20
20
|
# further.
|
21
21
|
def self.sanitize_history(history_data, watch_words, &sanitizing_block)
|
22
22
|
matchers = watch_words.map {|word| word.is_a?(Regexp) ? word : Regexp.new(word, true)}
|
23
|
-
history_data.dup
|
24
|
-
|
23
|
+
data = history_data.dup
|
24
|
+
data["a"].merge!(
|
25
|
+
"history" => data["a"]["history"].map {|entry| sanitize(entry, matchers, &sanitizing_block)}
|
25
26
|
)
|
27
|
+
data
|
26
28
|
end
|
27
29
|
|
28
30
|
# For each entry, we sanitize it if there's a matching handler. If there is no sanitizer, see if
|
29
31
|
# any data in the entry merit flagging against a watch word.
|
30
32
|
def self.sanitize(entry, matchers, &sanitizing_block)
|
31
33
|
ElmHistoryTools::Utils.transform_object(entry) do |elm_object|
|
32
|
-
constructor = elm_object["
|
34
|
+
constructor = elm_object["$"]
|
33
35
|
raise ElmObjectExpected unless constructor
|
34
36
|
|
35
37
|
# replace any records that need it
|
36
38
|
cleaned_object = elm_object.each_with_object({}) do |(key, value), hash|
|
37
|
-
if value.is_a?(Hash) && value["
|
39
|
+
if value.is_a?(Hash) && value["$"]
|
38
40
|
# we have an elm object -- sanitize that
|
39
41
|
hash[key] = sanitize(value, matchers, &sanitizing_block)
|
40
42
|
elsif value.is_a?(Hash)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elm_history_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Koppel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.
|
84
|
+
rubygems_version: 2.7.7
|
85
85
|
signing_key:
|
86
86
|
specification_version: 4
|
87
87
|
summary: Tools to work with Elm history exports.
|