sansom 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d1548d457d044bae13692b07bcb7a8374212be88
4
- data.tar.gz: 13e2ea4214d1b6a3c5b7c2c05421776f20dd9c92
3
+ metadata.gz: 9fe8ba21c0cab848b10f8484f8f38a0454d2f549
4
+ data.tar.gz: dccfd78c121e2b6f6bc5c01f42bce52f8809ea93
5
5
  SHA512:
6
- metadata.gz: e097de2bf1ea1b34754d9fde63983bc374d72e36a9cb446d275302824b1fc04183f1282b944add46b364ce1b5c7241520ce388eb53a4c09b702886748ce8a51e
7
- data.tar.gz: 13503646c81f33fb6ad3cb9004859fa3bd9036781ed5ac7a1b05c5797d0777303575d578b7231353e99803246736ff49ae833ba9c506d053d717b869772dc002
6
+ metadata.gz: 773fded808375146ea57bf266e68feb8ad2c27ee584590e568d98d9517401f24b07a52f6f8dabab5da0e34114617fcce3b610a5683a77c02c17a10f33b59d93b
7
+ data.tar.gz: f004a23139c2dd2b1664868507815e1f149064f0511d35a5804efe818f16eabbb1e199d7afd90aa24f9a4162c090891200d24ff4cb60499a1edda90dea3bdc86
data/README.md CHANGED
@@ -6,14 +6,22 @@ Scientific, philosophical, abstract web 'picowork' named after Sansom street in
6
6
  Philosophy
7
7
  -
8
8
 
9
- *A piece of software should not limit you to one way of thinking.*
9
+ ***A piece of software should not limit you to one way of thinking.***
10
10
 
11
11
  You can write a `Sansomable` for each logical unit of your API, but you also don't have to.
12
12
 
13
- You can also mount existing Rails/Sinatra apps in your `Sansomable`. But you also don't have to.
13
+ You can also mount existing Rails/Sinatra/Rack apps in your `Sansomable`. But you also don't have to.
14
14
 
15
15
  You can write one `Sansomable` for your entire API.
16
16
 
17
+ Fuck it.
18
+
19
+ ***A piece of software should not be a magic box.***
20
+
21
+ A web framework is, however simplistically, a tool to connect code to a URL's path.
22
+
23
+ A web framework doesn't provide an ORM, template rendering, nor change how ruby works to the point where you're not writing Ruby code but instead `Rails` or `Sinatra` code.
24
+
17
25
  Installation
18
26
  -
19
27
 
@@ -160,7 +168,7 @@ Notes
160
168
  -
161
169
 
162
170
  - `Sansom` does not pollute _any_ `Object` methods, including `initialize`
163
- - `Sansom` is under **190** lines of code at the time of writing. This includes
171
+ - `Sansom` is under **250** lines of code at the time of writing. This includes
164
172
  * Rack conformity & the DSL (`sansom.rb`)
165
173
  * Custom tree-based routing (`pine.rb`)
166
174
 
@@ -46,4 +46,10 @@ Here's an example
46
46
  0.0.7
47
47
 
48
48
  - Fixed bug where a wilcard path component would be ignored if it came last in the URL
49
- - Fixed a bug where async responses would be marked as bad by the fastlinter.
49
+ - Fixed a bug where async responses would be marked as bad by the fastlinter.
50
+
51
+ 0.1.0
52
+
53
+ - PUBLIC RELEASE!
54
+ - After block added
55
+ - Improved routing behavior & speed
@@ -4,7 +4,6 @@ require "rack"
4
4
 
5
5
  module Rack
6
6
  class Fastlint
7
- LintError = Class.new StandardError
8
7
  def self.response res
9
8
  return false unless res.kind_of?(Array) && res.count == 3
10
9
 
@@ -21,15 +20,15 @@ module Rack
21
20
  begin
22
21
  headers.each { |k,v|
23
22
  next if key =~ /^rack\..+$/
24
- throw LintError unless k.kind_of? String
25
- throw LintError unless v.kind_of? String
26
- throw LintError if k.downcase == "status"
27
- throw LintError unless k !~ /[:\n]/
28
- throw LintError unless k !~ /[-_]\z/
29
- throw LintError unless k =~ /\A[a-zA-Z][a-zA-Z0-9_-]*\z/
23
+ throw StandardError unless k.kind_of? String
24
+ throw StandardError unless v.kind_of? String
25
+ throw StandardError if k.downcase == "status"
26
+ throw StandardError unless k !~ /[:\n]/
27
+ throw StandardError unless k !~ /[-_]\z/
28
+ throw StandardError unless k =~ /\A[a-zA-Z][a-zA-Z0-9_-]*\z/
30
29
  }
31
30
 
32
- body.each { |part| throw LintError unless part.kind_of? String }
31
+ body.each { |part| throw StandardError unless part.kind_of? String }
33
32
  rescue StandardError
34
33
  return false
35
34
  end
@@ -6,10 +6,10 @@ require_relative "./rack/fastlint.rb"
6
6
 
7
7
  module Sansomable
8
8
  InvalidRouteError = Class.new StandardError
9
- HTTP_VERBS = [:get,:head, :post, :put, :delete, :patch, :options].freeze
10
- HANDLERS = ["puma", "unicorn", "thin", "webrick"].freeze
9
+ HTTP_VERBS = [:get,:head, :post, :put, :delete, :patch, :options, :link, :unlink, :trace].freeze
10
+ RACK_HANDLERS = ["puma", "unicorn", "thin", "webrick"].freeze
11
11
  NOT_FOUND = [404, {}, ["Not found."]].freeze
12
-
12
+
13
13
  def tree
14
14
  if @tree.nil?
15
15
  @tree = Pine::Node.new "ROOT"
@@ -19,49 +19,56 @@ module Sansomable
19
19
  end
20
20
 
21
21
  def call env
22
- return NOT_FOUND if tree.leaf?
22
+ return NOT_FOUND if tree.leaf? && tree.root?
23
23
 
24
24
  r = Rack::Request.new env
25
+ m = tree.match r.path_info, r.request_method
26
+
27
+ return NOT_FOUND if m.nil?
25
28
 
26
- if @before_block
27
- res = @before_block.call r
28
- return res if Rack::Fastlint.response res
29
+ if @before_block && @before_block.arity == 1
30
+ bres = @before_block.call r
31
+ return bres if Rack::Fastlint.response bres
29
32
  end
30
33
 
31
- m = tree.match r.path_info, r.request_method
32
-
33
- if m.nil?
34
- NOT_FOUND
35
- else
36
- if m.url_params.count > 0
37
- q = r.params.merge(m.url_params)
38
- s = q.map { |p| p.join '=' }.join("&")
39
- r.env["rack.request.query_hash"] = q
40
- r.env["rack.request.query_string"] = s
41
- r.env["QUERY_STRING"] = s
42
- r.instance_variable_set "@params", r.POST.merge(q)
43
- end
44
-
45
- if m.item.is_a? Proc
46
- m.item.call r
47
- elsif m.item.respond_to? :call
48
- r.env["PATH_INFO"] = m.remaining_path
49
- m.item.call r.env
50
- else
51
- raise InvalidRouteError, "Route handlers must be blocks or valid rack apps."
52
- end
34
+ if m.url_params.count > 0
35
+ q = r.params.merge m.url_params
36
+ s = q.map { |p| p.join '=' }.join '&'
37
+ r.env["rack.request.query_hash"] = q
38
+ r.env["rack.request.query_string"] = s
39
+ r.env["QUERY_STRING"] = s
40
+ r.instance_variable_set "@params", r.POST.merge(q)
53
41
  end
42
+
43
+ case m.item
44
+ when Proc then res = m.item.call r
45
+ else
46
+ raise InvalidRouteError, "Route handlers must be blocks or valid rack apps." unless m.item.respond_to? :call
47
+ r.env["PATH_INFO"] = m.remaining_path
48
+ res = m.item.call r.env
49
+ end
50
+
51
+ if @after_block && @after_block.arity == 2
52
+ ares = @after_block.call r, res
53
+ return ares if Rack::Fastlint.response ares
54
+ end
55
+
56
+ res
54
57
  end
55
58
 
56
59
  def start port=3001
57
60
  raise NoRoutesError if tree.leaf?
58
- Rack::Handler.pick(HANDLERS).run self, :Port => port
61
+ Rack::Handler.pick(RACK_HANDLERS).run self, :Port => port
59
62
  end
60
63
 
61
64
  def before &block
62
65
  @before_block = block
63
66
  end
64
67
 
68
+ def after &block
69
+ @after_block = block
70
+ end
71
+
65
72
  def method_missing meth, *args, &block
66
73
  path, item = *args.dup.push(block)
67
74
  return super unless path && item
@@ -4,35 +4,28 @@
4
4
 
5
5
  module Pine
6
6
  Result = Struct.new :item, :remaining_path, :url_params
7
-
7
+
8
8
  class Content
9
- attr_accessor :items, :map
9
+ attr_reader :items, :map
10
10
 
11
11
  def initialize
12
12
  @items = []
13
13
  @map = {}
14
14
  end
15
-
16
- def []= k,v
15
+
16
+ def set k,v
17
17
  @items << v if k == :map
18
18
  @map[k] = v unless k == :map
19
19
  end
20
-
21
- def [] k
22
- @items[k] if Numeric === k
23
- @map[k] unless Numeric === k
24
- end
25
20
  end
26
21
 
27
22
  class Node
28
- attr_reader :name, :parent
29
- attr_accessor :content
30
-
31
- def initialize name, content=Content.new
23
+ attr_reader :name, :parent, :content
24
+
25
+ def initialize name
32
26
  @name = name
33
- @content = content
27
+ @content = Content.new
34
28
  @children = {}
35
- @parent = nil
36
29
  end
37
30
 
38
31
  def root?
@@ -48,45 +41,33 @@ module Pine
48
41
  end
49
42
 
50
43
  def [] k
51
- child = @children[k]
52
- return child unless child.nil?
53
- child = @children.values.first
54
- return child if child.wildcard?
55
- nil
56
- # return @children[k] || @children.values.first
57
- end
58
-
59
- def create_and_save comp
60
- child = self.class.new comp
61
- child.instance_variable_set "@parent", self
62
- @children[comp] = child
63
- child
44
+ return @children[k] if @children.member? k
45
+ c = @children.values.first
46
+ return c if (c.wildcard? rescue false)
64
47
  end
65
48
 
66
49
  def << comp
67
- if comp.start_with? ":"
68
- @children.clear
69
- create_and_save comp
70
- else
71
- child = @children[comp]
72
- child = create_and_save comp if !child || (!child && child.leaf? && !child.wildcard?)
73
- child
50
+ child = self[comp]
51
+
52
+ if child.nil?
53
+ child = self.class.new comp
54
+ child.instance_variable_set "@parent", self
55
+ @children.reject!(&:leaf?) if child.wildcard?
56
+ @children[comp] = child
74
57
  end
75
- end
76
58
 
77
- def parse_path path, include_root=true
59
+ child
60
+ end
61
+
62
+ def parse_path path
78
63
  c = path.split "/"
79
- if include_root
80
- c[0] = '/'
81
- else
82
- c.delete_at(0) if c[0].empty?
83
- end
64
+ c[0] = '/'
84
65
  c.delete_at(-1) if c[-1].empty?
85
66
  c
86
67
  end
87
68
 
88
69
  def map_path path, item, key
89
- parse_path(path).inject(self) { |node, comp| node << comp }.content[key] = item
70
+ parse_path(path).inject(self) { |node, comp| node << comp }.content.set key, item
90
71
  path
91
72
  end
92
73
 
@@ -95,15 +76,18 @@ module Pine
95
76
  matched_params = {}
96
77
 
97
78
  walk = parse_path(path).inject self do |node, comp|
98
- next node[comp] if node.name == "ROOT"
99
- matched_comps << comp unless node.leaf?
100
- child = node[comp]
101
- matched_params[child.name[1..-1]] = comp if child.wildcard?
102
- child
79
+ break node if node.leaf?
80
+ next node[comp] if node.root?
81
+
82
+ c = node[comp]
83
+ break node if c.nil?
84
+ matched_comps << comp
85
+ matched_params[c.name[1..-1]] = comp if c.wildcard?
86
+ c
103
87
  end
104
88
 
105
89
  return nil if walk.nil?
106
- return nil if walk.root? #rescue true
90
+ return nil if walk.root?
107
91
 
108
92
  c = walk.content
109
93
  subpath = path.sub "/#{matched_comps.join("/")}", ""
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "sansom"
7
- s.version = "0.0.7"
7
+ s.version = "0.1.0"
8
8
  s.authors = ["Nathaniel Symer"]
9
9
  s.email = ["nate@natesymer.com"]
10
10
  s.summary = "Scientific, philosophical, abstract web 'picowork' named after Sansom street in Philly, near where it was made."
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sansom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathaniel Symer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-01 00:00:00.000000000 Z
11
+ date: 2014-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler